{ "cells": [ { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "# Montecarlo Packet Visualization" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "This visualization tool plots the `RPackets` that are generated by the [Montecarlo](https://tardis-sn.github.io/tardis/physics/montecarlo/index.html) method and creates an animated plot that contains the packet trajectories as they move away from the photosphere.\n", "The properties of individual RPackets are taken from the [rpacket_tracker](https://tardis-sn.github.io/tardis/io/output/how_to_rpacket_tracking.html). " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from tardis import run_tardis\n", "from tardis.io.configuration.config_reader import Configuration\n", "from tardis.io.atom_data.util import download_atom_data\n", "import plotly.express as px\n", "import plotly.graph_objects as go\n", "import math\n", "import pandas as pd\n", "import numpy as np\n", "import random" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Download atom data\n", "download_atom_data('kurucz_cd23_chianti_H_He')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Reading the Configuration stored in `tardis_example.yml` into config\n", "\n", "config = Configuration.from_yaml(\"tardis_example.yml\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# changing config file for plotting 15 packets\n", "\n", "config[\"montecarlo\"][\"tracking\"][\"track_rpacket\"]=True\n", "config[\"montecarlo\"][\"seed\"]= 457\n", "config[\"montecarlo\"][\"no_of_packets\"]=10\n", "config[\"montecarlo\"][\"iterations\"]=1\n", "config[\"montecarlo\"][\"last_no_of_packets\"]=15\n", "config[\"montecarlo\"][\"no_of_virtual_packets\"]=3" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": true }, "outputs": [], "source": [ "sim = run_tardis(config, show_progress_bars=False)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# accessing the rpacket_tracker dataframe\n", "sim.transport.transport_state.rpacket_tracker_df" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "## Finding packet coordinates\n", "\n", "\\\n", "\n", "\n", "

The diagram above shows the packet trajectory as it starts from photosphere `P0` and continues to move along the subsequent points `P1`, `P2`, and so on.\n", "\n", "
\n", "\n", "Note\n", " \n", "Here `μ` represents the direction of packet propagation with respect to the radial line.\n", " \n", "
\n", "\n", "To determine the polar coordinates of any arbitrary point, say `P2`, we need `r2` and `θ2`. `r2` is already present in the array obtained from the simulation. To determine `θ2`, we use sine rule and apply it to the triangle `OP1P2`, where `O` is the center.\n", "\n", "$$\n", "\\frac{r_{2}}{\\sin(\\pi - \\mu_{1})} = \\frac{r_{1}}{\\sin(\\alpha)}\n", "$$\n", "\n", "Now, writing `α` in terms of `μ1` and `θ2`\n", "\n", "$$ \n", "α = μ_{1} - θ_{2}\n", "$$\n", "$$\n", "\\frac{r_{2}}{\\sin(\\pi - \\mu_{1})} = \\frac{r_{1}}{\\sin(μ_{1} - θ_{2})}\n", "$$\n", "\n", "Thus,\n", "\n", "$$ \n", "θ_{2} = -\\sin^{-1}(\\frac{r1}{r2}\\sin(\\mu_{1})) + \\mu_{1}\n", "$$\n", "\n", "Hence, for `ith` point, `θ` will be:\n", "\n", "$$ \n", "θ_{i} = -\\sin^{-1}(\\frac{r_{i-1}}{r_{i}}\\sin(\\mu_{i-1})) + \\mu_{i-1}\n", "$$" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# function for getting x y coordinates and interactions for a packet\n", "def get_x_y_ints_with_theta_init(r_track,mu_track,time,last_interaction_type,direction=\"normal\",theta_initial=0):\n", " xs,ys,theta,ints = [],[],[],[]\n", " \n", " for i in range(len(r_track)):\n", " if(i==0):\n", " theta.append(theta_initial)\n", " else:\n", " if(direction == 'random' or direction == 'r'):\n", " multiplier = random.choice([-1,1])\n", " elif(direction == 'opposite' or direction == 'o'):\n", " multiplier = -1\n", " else:\n", " multiplier = 1\n", " if (r_track[i]X: %{x}'+\n", " '
Y: %{y}
'+\n", " 'Last Interaction: %{text}',\n", " text = [interaction_from_num.get(ints[i][j]) for j in range(len(xs[i]))],\n", " line = dict(color=\"darkslategrey\"),\n", "# line_shape = \"spline\",\n", " marker = dict(opacity = [interaction_opacity_from_num.get(ints[i][j]) for j in range(len(xs[i]))],color=[interaction_color_from_num.get(ints[i][j]) for j in range(len(xs[i]))])\n", " ))\n", "\n", "#adding legends\n", "fig.add_trace(go.Scatter(\n", " x=[9999999],\n", " y=[0],\n", " legendgroup=\"a\",\n", " opacity=1,\n", " legendgrouptitle=dict(font=dict(color=\"#444\"),text=\"Interaction Type:\"),\n", " mode=\"lines+markers\",\n", " name=\"Escattering\",\n", " hoverlabel=dict(font=dict(color=\"#222\")),\n", " marker = dict(color=\"#3366FF\"),\n", "))\n", "fig.add_trace(go.Scatter(\n", " x=[9999999],\n", " y=[0],\n", " legendgroup=\"a\",\n", " opacity=1,\n", " mode=\"lines+markers\",\n", " name=\"Line\",\n", " marker = dict(color=\"#FF3300\"),\n", "))\n", "\n", "\n", "# Set figure size\n", "fig.layout.plot_bgcolor = '#fafafa'\n", "fig.layout.paper_bgcolor = '#fafafa'\n", "\n", "fig.update_layout(width=900, height=900,\n", " title=\"Packet Trajectories\",\n", " title_font_color=\"#444\",\n", " updatemenus=[dict(type=\"buttons\",\n", " pad=dict(t=750),\n", " buttons=[dict(label=\"Play\",\n", " method=\"animate\",\n", " args=[None])])])\n", "\n", "# creating frames for animation\n", "def get_frames(l):\n", " frames=[]\n", " for i in range(len(xs)):\n", " frames.append(go.Scatter(\n", " x=xs[i].tolist()[0:l],\n", " y=ys[i].tolist()[0:l],\n", " mode=\"markers+lines\",\n", " name=\"Packet \"+str(i+1),\n", " showlegend=False,\n", " hovertemplate =\n", " 'X: %{x}'+\n", " '
Y: %{y}
'+\n", " 'Last Interaction: %{text}',\n", " text = [interaction_from_num.get(ints[i][j]) for j in range(len(xs[i]))],\n", " line = dict(color=\"darkslategrey\"),\n", " # line_shape = \"spline\",\n", " marker = dict(opacity = [interaction_opacity_from_num.get(ints[i][j]) for j in range(len(xs[i]))],color=[interaction_color_from_num.get(ints[i][j]) for j in range(len(xs[i]))])\n", " ))\n", " return frames\n", " \n", "fig.frames=[go.Frame(data=get_frames(i)) for i in range(max_size+1)]\n", "\n", "fig.show(renderer=\"notebook_connected\")" ] } ], "metadata": { "interpreter": { "hash": "6890d83cfa6c65bebc4bd449872c06a268510d8b8ae8c923ce6786e6c4796836" }, "kernelspec": { "display_name": "Python 3 (ipykernel)", "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.11.5" } }, "nbformat": 4, "nbformat_minor": 4 }