diff --git a/docs/io/images/energy_level_widget_demo.gif b/docs/io/images/energy_level_widget_demo.gif
new file mode 100644
index 00000000000..a9242e39b00
Binary files /dev/null and b/docs/io/images/energy_level_widget_demo.gif differ
diff --git a/docs/io/images/energy_level_widget_options.gif b/docs/io/images/energy_level_widget_options.gif
new file mode 100644
index 00000000000..d3c7361b057
Binary files /dev/null and b/docs/io/images/energy_level_widget_options.gif differ
diff --git a/docs/io/visualization/how_to_generating_widgets.ipynb b/docs/io/visualization/how_to_generating_widgets.ipynb
index 8b32fb68898..7e7b2a9e499 100644
--- a/docs/io/visualization/how_to_generating_widgets.ipynb
+++ b/docs/io/visualization/how_to_generating_widgets.ipynb
@@ -14,7 +14,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "First create and run a simulation that we can use to generate widgets (more details about running simulation in [Quickstart](https://tardis-sn.github.io/tardis/quickstart/quickstart.html) section):"
+ "First create and run a simulation that we can use to generate widgets (more details about running simulation in [Quickstart](https://tardis-sn.github.io/tardis/quickstart/quickstart.html) section):\n"
]
},
{
@@ -33,16 +33,16 @@
"from tardis.io.atom_data.util import download_atom_data\n",
"\n",
"# We download the atomic data needed to run the simulation\n",
- "download_atom_data('kurucz_cd23_chianti_H_He')\n",
+ "download_atom_data(\"kurucz_cd23_chianti_H_He\")\n",
"\n",
- "sim = run_tardis('tardis_example.yml', virtual_packet_logging=True)"
+ "sim = run_tardis(\"tardis_example.yml\", virtual_packet_logging=True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
- "Now, import functions & class to create widgets from `visualization` subpackage:"
+ "Now, import functions & class to create widgets from `visualization` subpackage:\n"
]
},
{
@@ -60,6 +60,7 @@
" shell_info_from_simulation,\n",
" shell_info_from_hdf,\n",
" LineInfoWidget,\n",
+ " GrotrianWidget,\n",
")"
]
},
@@ -68,9 +69,10 @@
"metadata": {},
"source": [
"## Shell Info Widget\n",
+ "\n",
"This widget allows you to explore chemical abundances of each shell - all the way from elements to ions to levels - by just clicking on the rows you want to explore!\n",
"\n",
- "There are two ways in which you can generate the widget:"
+ "There are two ways in which you can generate the widget:\n"
]
},
{
@@ -78,7 +80,8 @@
"metadata": {},
"source": [
"### Using a Simulation object\n",
- "We will use the simulation object we created in the beginning, `sim` to generate shell info widget. Then simply display it to start using."
+ "\n",
+ "We will use the simulation object we created in the beginning, `sim` to generate shell info widget. Then simply display it to start using.\n"
]
},
{
@@ -104,7 +107,7 @@
"\n",
"![Shell Info Widget Demo](../images/shell_info_widget_demo.gif)\n",
"\n",
- "Use the button at the top of this page to run the notebook in interactively to use the widgets!"
+ "Use the button at the top of this page to run the notebook in interactively to use the widgets!\n"
]
},
{
@@ -112,7 +115,8 @@
"metadata": {},
"source": [
"### Using a saved simulation (HDF file)\n",
- "Alternatively, if you have a TARDIS simulation model saved on your disk as an HDF file, you can also use it to generate the shell info widget."
+ "\n",
+ "Alternatively, if you have a TARDIS simulation model saved on your disk as an HDF file, you can also use it to generate the shell info widget.\n"
]
},
{
@@ -136,16 +140,17 @@
"metadata": {},
"source": [
"## Line Info Widget\n",
+ "\n",
"This widget lets you explore the atomic lines responsible for producing features in the simulated spectrum.\n",
"\n",
- "You can select any wavelength range in the spectrum interactively to display a table giving the fraction of packets that experienced their last interaction with each species. Using toggle buttons, you can specify whether to filter the selected range by the emitted or absorbed wavelengths of packets. Clicking on a row in the species table, shows packet counts for each last line interaction of the selected species, which can be grouped in several ways."
+ "You can select any wavelength range in the spectrum interactively to display a table giving the fraction of packets that experienced their last interaction with each species. Using toggle buttons, you can specify whether to filter the selected range by the emitted or absorbed wavelengths of packets. Clicking on a row in the species table, shows packet counts for each last line interaction of the selected species, which can be grouped in several ways.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
- "To generate line info widget, we will again use the simulation object `sim` and then display the widget:"
+ "To generate line info widget, we will again use the simulation object `sim` and then display the widget:\n"
]
},
{
@@ -169,7 +174,7 @@
"source": [
"You can interact with this widget (which again won't be visible if you're viewing this notebook in our docs as an html page) like this:\n",
"\n",
- "![Line Info Widget Demo](../images/line_info_widget_demo.gif)"
+ "![Line Info Widget Demo](../images/line_info_widget_demo.gif)\n"
]
},
{
@@ -179,11 +184,58 @@
"
\n",
"\n",
"Note\n",
- " \n",
+ "\n",
"The virtual packet logging capability must be active in order to produce virtual packets' spectrum in `Line Info Widget`. Thus, make sure to set `virtual_packet_logging: True` in your configuration file. It should be added under `virtual` property of `spectrum` property, as described in [configuration schema](https://tardis-sn.github.io/tardis/using/components/configuration/configuration.html#spectrum).\n",
"\n",
- "
"
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Energy Level Diagram\n",
+ "\n",
+ "This widget lets you explore and visualize the various level populations and line interactions in a simulation in the form of an Energy Level Diagram.\n",
+ "\n",
+ "You can select any ion present in the simulation and filter the transitions by wavelength or model shell to display an energy level diagram, where:\n",
+ "\n",
+ "- The horizontal lines represent the energy levels. The thickness of each line shows the relative population of that energy level, with thicker lines being more populated.\n",
+ "- The arrows represent the line interactions between levels, with the arrow direction giving the direction of the transition. The thickness of each arrow also shows the number of packets that underwent the transition while the wavelength is given by the color.\n",
+ "\n",
+ "In addition, you can also select between linear- and log-scaling for the y-axis (which represents the energy of each level) and the maximum number of levels to display, beginning from the lowest energy levels.\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "To generate the energy level diagram, we will again use the simulation object `sim` and then display the widget:\n"
]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "energy_level_widget = GrotrianWidget.from_simulation(sim)\n",
+ "energy_level_widget.display()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "You can interact with this widget (which again won't be visible if you're viewing this notebook in our docs as an html page) like this:\n",
+ "\n",
+ "![Energy Level Diagram Demo](../images/energy_level_widget_options.gif)\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": []
}
],
"metadata": {
diff --git a/docs/io/visualization/using_widgets.rst b/docs/io/visualization/using_widgets.rst
index bd6fa8ef442..712dc53f1de 100644
--- a/docs/io/visualization/using_widgets.rst
+++ b/docs/io/visualization/using_widgets.rst
@@ -178,4 +178,40 @@ There are also several other options in the modebar which we have not explained
you remember to click back on the **Box Select** option for making selections on
spectrum.
+Energy Level Diagram
+################
+
+This widget lets you visualize the last line interactions
+
+.. image:: ../images/energy_level_widget_demo.gif
+ :alt: Demo of Energy Level Diagram
+
+By selecting an ion on the widget, you can see its energy level diagram, which
+also shows information about the last line interactions experienced by packets
+in the simulation.
+
+The y-axis of the plot represents energy while the horizontal lines show
+discrete energy levels. The thickness of each line represents the level
+population, with thicker lines representing a greater population than the thin lines.
+
+Arrows represent the line interactions experienced by packets. Upwards arrows
+show excitation from lower energy levels to higher levels and downward arrows
+show de-excitation from higher energy levels to lower levels. The thickness of
+each arrow represents the number of packets that underwent that interaction,
+with thicker lines representing more packets than the thin lines.
+The wavelength of the transition is given by the color.
+
+Setting Other Options
+-----------------
+You can select the range on which to filter the wavelength using the slider.
+You can also select the model shell by which to filter the last line interactions
+and the level populations. If no shell is selected, then all the last line
+interactions are plotted and the level populations are averaged across all shells
+in the simulation. You can also set the maximum number of levels to show on the plot.
+
+Lastly, you can also set the scale of the y-axis: Linear or Log.
+
+.. image:: ../images/energy_level_widget_options.gif
+ :alt: Demo of using options
+
.. Toggle legend
diff --git a/tardis/visualization/__init__.py b/tardis/visualization/__init__.py
index 4b806fdd147..19e4faadeac 100644
--- a/tardis/visualization/__init__.py
+++ b/tardis/visualization/__init__.py
@@ -7,5 +7,6 @@
shell_info_from_hdf,
)
from tardis.visualization.widgets.line_info import LineInfoWidget
+from tardis.visualization.widgets.grotrian import GrotrianWidget
from tardis.visualization.widgets.custom_abundance import CustomAbundanceWidget
from tardis.visualization.tools.sdec_plot import SDECPlotter
diff --git a/tardis/visualization/widgets/grotrian.py b/tardis/visualization/widgets/grotrian.py
index f15e6132698..6c3558f769c 100644
--- a/tardis/visualization/widgets/grotrian.py
+++ b/tardis/visualization/widgets/grotrian.py
@@ -4,6 +4,7 @@
This widget displays a Grotrian Diagram of the last line interactions of the simulation packets
"""
from tardis.analysis import LastLineInteraction
+from tardis.util.base import species_tuple_to_string, species_string_to_tuple
from tardis.util.base import int_to_roman
import plotly.graph_objects as go
from plotly.subplots import make_subplots
@@ -17,12 +18,29 @@
ANGSTROM_SYMBOL = "\u212B"
+def is_zero_defined(transform):
+ """
+ Utility function to decide if a certain transform is defined at zero
+
+ Parameters
+ ----------
+ transform : function
+
+ Returns
+ -------
+ bool
+ True if transform is defined at 0 else False
+ """
+ if transform in [np.log, np.log10]:
+ return True
+ return False
+
+
def standardize(
values,
transform=lambda x: x,
min_value=None,
max_value=None,
- zero_undefined=False,
zero_undefined_offset=0,
):
"""
@@ -39,9 +57,6 @@ def standardize(
The lower bound of the range
max_value : float, optional
The upper bound of the range
- zero_undefined : bool, optional
- When applying transformations (like log) where output of 0 is undefined, set this to True
- Default value is False
zero_undefined_offset : int, optional
This is useful for log transformation because log(0) is -inf.
Hence, value=0 gives y=0 while the
@@ -53,6 +68,8 @@ def standardize(
pandas.Series
Values after standardization
"""
+ zero_undefined = is_zero_defined(transform) # Is function defined at 0?
+
if zero_undefined and zero_undefined_offset == 0:
raise ValueError(
"If zero of the transformation is undefined, then provide an offset greater than 0"
@@ -61,18 +78,26 @@ def standardize(
# Compute lower and upper bounds of values
if min_value is None:
if zero_undefined:
- min_value = values[values > 0].min()
+ min_value = (
+ values[values > 0].min() if len(values[values > 0]) > 0 else 0
+ )
else:
- min_value = values.min()
+ min_value = values.min() if len(values) > 0 else 0
if max_value is None:
if zero_undefined:
- max_value = values[values > 0].max()
+ max_value = (
+ values[values > 0].max() if len(values[values > 0]) > 0 else 0
+ )
else:
- max_value = values.max()
+ max_value = values.max() if len(values) > 0 else 0
# Apply transformation if given
- transformed_min_value = transform(min_value)
- transformed_max_value = transform(max_value)
+ transformed_min_value = (
+ transform(min_value) if (min_value > 0 or not zero_undefined) else 0
+ )
+ transformed_max_value = (
+ transform(max_value) if (max_value > 0 or not zero_undefined) else 0
+ )
transformed_values = transform(values)
# Compute range
@@ -85,7 +110,7 @@ def standardize(
) / value_range
if zero_undefined:
transformed_values = transformed_values + zero_undefined_offset
- transformed_values.mask(values == 0, 0, inplace=True)
+ transformed_values = np.where(values == 0, 0, transformed_values)
else:
# If only single value present in table, then place it at 0
transformed_values = 0 * values
@@ -93,8 +118,9 @@ def standardize(
return transformed_values
-class GrotrianWidget:
- """Class for the Grotrian Diagram
+class GrotrianPlot:
+ """
+ Class for the Grotrian Diagram
Parameters
----------
@@ -136,7 +162,7 @@ class GrotrianWidget:
Default value is packet_out_nu
y_scale : {"Log", "Linear"}
The scale to plot the energy levels on the y-axis
- Default value is Linear
+ Default value is Log
cmapname : str
The name of the colormap used to denote wavelengths. Default value is "rainbow"
level_width_scale : float
@@ -159,7 +185,8 @@ class GrotrianWidget:
@classmethod
def from_simulation(cls, sim, **kwargs):
- """Creates a GrotrianWidget object from a Simulation object
+ """
+ Creates a GrotrianPlot object from a Simulation object
Parameters
----------
@@ -168,8 +195,8 @@ def from_simulation(cls, sim, **kwargs):
Returns
-------
- tardis.visualization.widgets.grotrian.GrotrianWidget
- GrotrianWidget object
+ tardis.visualization.widgets.grotrian.GrotrianPlot
+ GrotrianPlot object
"""
atom_data = sim.plasma.atomic_data.atom_data
level_energy_data = pd.Series(
@@ -223,7 +250,7 @@ def __init__(
self._level_width_transform = np.log # Scale of the level widths
self._population_spacer = np.geomspace # To space width bar counts
### Scale of the y-axis
- self._y_scale = "Linear"
+ self._y_scale = "Log"
self._y_coord_transform = self.Y_SCALE_OPTION[self._y_scale]
### Define default parameters for visual elements related to transitions
@@ -276,7 +303,7 @@ def max_levels(self, value):
assert type(value) is int
self._max_levels = value
self._compute_level_data()
- self._compute_transitions()
+ self.reset_selected_plot_wavelength_range() # calls _compute_transitions() as well
@property
def level_diff_threshold(self):
@@ -332,9 +359,6 @@ def set_ion(self, atomic_number, ion_number):
self._atomic_number = atomic_number
self._ion_number = ion_number
self._compute_level_data()
- print(
- "Changing the ion will reset custom wavelength ranges, if any were set"
- )
# Reset any custom wavelengths if user changes ion
self.reset_selected_plot_wavelength_range() # Also computes transition lines so we don't need to call it "_compute_transitions()" explicitly
@@ -457,42 +481,44 @@ def _compute_transitions(self):
]
### Compute default wavelengths if not set by user
- if self.min_wavelength is None: # Compute default wavelength
- self._min_wavelength = np.min(
- np.concatenate(
- (excite_lines.wavelength, deexcite_lines.wavelength)
+ if len(excite_lines) + len(deexcite_lines) > 0:
+ if self.min_wavelength is None: # Compute default wavelength
+ self._min_wavelength = np.min(
+ np.concatenate(
+ (excite_lines.wavelength, deexcite_lines.wavelength)
+ )
)
- )
- if self.max_wavelength is None: # Compute default wavelength
- self._max_wavelength = np.max(
- np.concatenate(
- (excite_lines.wavelength, deexcite_lines.wavelength)
+ if self.max_wavelength is None: # Compute default wavelength
+ self._max_wavelength = np.max(
+ np.concatenate(
+ (excite_lines.wavelength, deexcite_lines.wavelength)
+ )
)
- )
-
- ### Remove the rows outside the wavelength range for the plot
- excite_lines = excite_lines.loc[
- (excite_lines.wavelength >= self.min_wavelength)
- & (excite_lines.wavelength <= self.max_wavelength)
- ]
- deexcite_lines = deexcite_lines.loc[
- (deexcite_lines.wavelength >= self.min_wavelength)
- & (deexcite_lines.wavelength <= self.max_wavelength)
- ]
- ### Compute the standardized log number of electrons for arrow line width
- transition_width_coefficient = standardize(
- np.concatenate(
- (excite_lines.num_electrons, deexcite_lines.num_electrons)
- ),
- transform=self._transition_width_transform,
- )
- excite_lines[
- "transition_width_coefficient"
- ] = transition_width_coefficient[: len(excite_lines)]
- deexcite_lines[
- "transition_width_coefficient"
- ] = transition_width_coefficient[len(excite_lines) :]
+ ### Remove the rows outside the wavelength range for the plot
+ excite_lines = excite_lines.loc[
+ (excite_lines.wavelength >= self.min_wavelength)
+ & (excite_lines.wavelength <= self.max_wavelength)
+ ]
+ deexcite_lines = deexcite_lines.loc[
+ (deexcite_lines.wavelength >= self.min_wavelength)
+ & (deexcite_lines.wavelength <= self.max_wavelength)
+ ]
+
+ ### Compute the standardized log number of electrons for arrow line width
+ transition_width_coefficient = standardize(
+ np.concatenate(
+ (excite_lines.num_electrons, deexcite_lines.num_electrons)
+ ),
+ transform=self._transition_width_transform,
+ zero_undefined_offset=1e-3,
+ )
+ excite_lines[
+ "transition_width_coefficient"
+ ] = transition_width_coefficient[: len(excite_lines)]
+ deexcite_lines[
+ "transition_width_coefficient"
+ ] = transition_width_coefficient[len(excite_lines) :]
self.excite_lines = excite_lines
self.deexcite_lines = deexcite_lines
@@ -554,7 +580,6 @@ def _compute_level_data(self):
self.level_data["level_width_coefficient"] = standardize(
self.level_data.population,
transform=self._level_width_transform,
- zero_undefined=True,
zero_undefined_offset=1e-3,
)
@@ -569,7 +594,6 @@ def _draw_energy_levels(self):
self.level_data["y_coord"] = standardize(
self.level_data.energy,
transform=self._y_coord_transform,
- zero_undefined=True,
zero_undefined_offset=0.1,
)
@@ -602,7 +626,7 @@ def _draw_energy_levels(self):
self.fig.add_annotation(
x=self.x_max + 0.1,
y=level_info.y_coord,
- text=f"n={level_number}",
+ text=f"{level_number}",
showarrow=False,
xref="x2",
yref="y2",
@@ -681,6 +705,7 @@ def _draw_transitions(self, is_excitation):
lines["color_coefficient"] = standardize(
lines.wavelength,
transform=self._wavelength_color_transform,
+ zero_undefined_offset=1e-5,
min_value=self.min_wavelength,
max_value=self.max_wavelength,
)
@@ -871,21 +896,23 @@ def _draw_transition_color_scale(self):
def display(self):
"""
- Parent function to draw the widget (calls other draw methods independently)
+ Function to draw the plot and the reference scales (calls other draw methods independently)
"""
### Create figure and set metadata
- self.fig = make_subplots(
- rows=1,
- cols=2,
- column_width=[0.3, 0.7],
- specs=[[{}, {}]],
- horizontal_spacing=0.14,
+ self.fig = go.FigureWidget(
+ make_subplots(
+ rows=1,
+ cols=2,
+ column_width=[0.3, 0.7],
+ specs=[[{}, {}]],
+ horizontal_spacing=0.14,
+ )
)
# Update fig layout
self.fig.update_layout(
title=(
- f"Grotrian Diagram for {self.atomic_name} {int_to_roman(self.ion_number + 1)} "
+ f"Energy Level Diagram for {self.atomic_name} {int_to_roman(self.ion_number + 1)} "
f"(Shell: {self.shell if self.shell is not None else 'All'})"
),
title_x=0.5,
@@ -939,9 +966,246 @@ def display(self):
)
### Create transition lines and corresponding width and color scales
- self._draw_transitions(is_excitation=True)
- self._draw_transitions(is_excitation=False)
- self._draw_transition_width_scale()
- self._draw_transition_color_scale()
+ if len(self.excite_lines) > 0:
+ self._draw_transitions(is_excitation=True)
+
+ if len(self.deexcite_lines) > 0:
+ self._draw_transitions(is_excitation=False)
+
+ if len(self.excite_lines) + len(self.deexcite_lines) > 0:
+ self._draw_transition_width_scale()
+ self._draw_transition_color_scale()
+
+ return self.fig
+
+
+class GrotrianWidget:
+ """
+ A wrapper class for the Grotrian Diagram, containing the Grotrian Plot and the IpyWidgets
+
+ Parameters
+ ----------
+ plot : tardis.visualization.widgets.grotrian.GrotrianPlot
+ GrotrianPlot object
+ num_shells : int
+ Number of shells in the sim.simulation_state.v_inner
+ """
+
+ @classmethod
+ def from_simulation(cls, sim, **kwargs):
+ """
+ Creates a GrotrianWidget object from a Simulation object
+
+ Parameters
+ ----------
+ sim : tardis.simulation.Simulation
+ TARDIS simulation object
+ Returns
+ -------
+ tardis.visualization.widgets.grotrian.GrotrianWidget
+ GrotrianWidget object
+ """
+ plot = GrotrianPlot.from_simulation(sim, **kwargs)
+ num_shells = len(sim.simulation_state.v_inner)
+ return cls(plot, num_shells, **kwargs)
+
+ def __init__(self, plot, num_shells, **kwargs):
+ self.plot = plot
+ self.num_shells = num_shells
+
+ species_list = self._get_species()
+ self.ion_selector = ipw.Dropdown(
+ options=species_list,
+ index=0,
+ description="Ion",
+ )
+ self.plot.set_ion(*species_string_to_tuple(self.ion_selector.value))
+ self.ion_selector.observe(
+ self._ion_change_handler,
+ names="value",
+ )
+ self.ion_selector.observe(
+ self._wavelength_resetter,
+ names="value",
+ )
+
+ shell_list = ["All"] + [str(i) for i in range(1, num_shells + 1)]
+ self.shell_selector = ipw.Dropdown(
+ options=shell_list,
+ index=0,
+ description="Shell",
+ )
+ self.shell_selector.observe(
+ lambda change: self._change_handler(
+ "shell", None if change["new"] == "All" else int(change["new"])
+ ),
+ names="value",
+ )
+ self.shell_selector.observe(
+ self._wavelength_resetter,
+ names="value",
+ )
+
+ self.max_level_selector = ipw.BoundedIntText(
+ value=plot.max_levels,
+ min=1,
+ max=40,
+ step=1,
+ description="Max Levels",
+ )
+ self.max_level_selector.observe(
+ lambda change: self._change_handler("max_levels", change["new"]),
+ names="value",
+ )
+ self.max_level_selector.observe(
+ self._wavelength_resetter,
+ names="value",
+ )
+
+ self.y_scale_selector = ipw.ToggleButtons(
+ options=GrotrianPlot.Y_SCALE_OPTION.keys(),
+ index=1,
+ description="Y-Scale",
+ layout=ipw.Layout(width="auto"),
+ style={"button_width": "100px"},
+ )
+ self.y_scale_selector.observe(
+ lambda change: self._change_handler("y_scale", change["new"]),
+ names="value",
+ )
+
+ self.wavelength_range_selector = ipw.FloatRangeSlider(
+ value=[self.plot.min_wavelength, self.plot.max_wavelength],
+ min=self.plot.min_wavelength,
+ max=self.plot.max_wavelength,
+ step=0.1,
+ description="Wavelength",
+ layout=ipw.Layout(width="605px"),
+ readout_format=".1e",
+ )
+ self.wavelength_range_selector.observe(
+ self._wavelength_change_handler,
+ names="value",
+ )
+
+ def _get_species(self):
+ """
+ Computes the ions list for the ion dropdown of the plot
+ """
+ line_interaction_analysis = self.plot._line_interaction_analysis
+ selected_species_group = line_interaction_analysis[
+ self.plot.filter_mode
+ ].last_line_in.groupby(["atomic_number", "ion_number"])
+
+ if selected_species_group.groups:
+ selected_species_symbols = [
+ species_tuple_to_string(item)
+ for item in selected_species_group.groups.keys()
+ ]
+ return selected_species_symbols
+
+ def _change_handler(self, attribute, value):
+ """
+ Generic function to update the configurable attributes of GrotrianPlot object
+
+ Parameters
+ ----------
+ attribute : str
+ The name of the attribute of the GrotrianPlot object
+ value :
+ The new value of the attribute
+ """
+ index = self.fig.children.index(self.plot.fig)
+ setattr(self.plot, attribute, value) # Set the value of the attribute
+
+ # Set the updated plot in the figure
+ children_list = list(self.fig.children)
+ children_list[index] = self.plot.display()
+ self.fig.children = tuple(children_list)
+
+ def _ion_change_handler(self, change):
+ """
+ Function to update ion of GrotrianPlot object
+
+ Parameters
+ ----------
+ change : dict
+ Change information of the event
+ """
+ atomic_number, ion_number = species_string_to_tuple(change["new"])
+ index = self.fig.children.index(self.plot.fig)
+ self.plot.set_ion(atomic_number, ion_number)
+
+ # Set the updated plot in the figure
+ children_list = list(self.fig.children)
+ children_list[index] = self.plot.display()
+ self.fig.children = tuple(children_list)
+ # self._wavelength_resetter()
+
+ def _wavelength_change_handler(self, change):
+ """
+ Function to update the wavelength range of GrotrianPlot object
+
+ Parameters
+ ----------
+ change : dict
+ Change information of the event
+ """
+ min_wavelength, max_wavelength = change["new"]
+ index = self.fig.children.index(self.plot.fig)
+ setattr(self.plot, "min_wavelength", min_wavelength)
+ setattr(self.plot, "max_wavelength", max_wavelength + 1)
+
+ # Set the updated plot in the figure
+ children_list = list(self.fig.children)
+ children_list[index] = self.plot.display()
+ self.fig.children = tuple(children_list)
+
+ def _wavelength_resetter(self, change):
+ """
+ Resets the range of the wavelength slider whenever the ion, level or shell changes
+ """
+ min_wavelength = self.plot.min_wavelength
+ max_wavelength = self.plot.max_wavelength
+
+ if min_wavelength is None or max_wavelength is None:
+ self.wavelength_range_selector.layout.visibility = "hidden"
+ return
+
+ elif min_wavelength == max_wavelength:
+ self.wavelength_range_selector.layout.visibility = "visible"
+ self.wavelength_range_selector.disabled = True
+ else:
+ self.wavelength_range_selector.layout.visibility = "visible"
+ self.wavelength_range_selector.disabled = False
+
+ self.wavelength_range_selector.min = 0.0
+ self.wavelength_range_selector.max = max_wavelength
+ self.wavelength_range_selector.min = min_wavelength
+ self.wavelength_range_selector.value = [
+ self.wavelength_range_selector.min,
+ self.wavelength_range_selector.max,
+ ]
+
+ def display(self):
+ """
+ Function to render the Grotrian Widget containing the plot and IpyWidgets together
+ """
+ fig = self.plot.display()
+ self.fig = ipw.VBox(
+ [
+ ipw.HBox(
+ [
+ self.ion_selector,
+ self.shell_selector,
+ self.max_level_selector,
+ ]
+ ),
+ ipw.HBox(
+ [self.y_scale_selector, self.wavelength_range_selector]
+ ),
+ fig,
+ ]
+ )
return self.fig
diff --git a/tardis/visualization/widgets/grotrian_mockup.ipynb b/tardis/visualization/widgets/grotrian_mockup.ipynb
index e77d5367382..870181cebc7 100644
--- a/tardis/visualization/widgets/grotrian_mockup.ipynb
+++ b/tardis/visualization/widgets/grotrian_mockup.ipynb
@@ -59,13 +59,13 @@
}
],
"source": [
- "from tardis.io.config_reader import Configuration\n",
+ "from tardis.io.configuration.config_reader import Configuration\n",
"from tardis.simulation import Simulation\n",
"from tardis.plasma.standard_plasmas import assemble_plasma\n",
"from tardis.model import SimulationState\n",
"from tardis.io.atom_data import AtomData\n",
"from tardis.visualization.widgets.grotrian import GrotrianWidget\n",
- "from tardis.io.config_internal import get_data_dir\n",
+ "from tardis.io.configuration.config_internal import get_data_dir\n",
"from plotly.offline import init_notebook_mode\n",
"import plotly.io as pio\n",
"import os\n",
@@ -83,22 +83,11 @@
"name": "stderr",
"output_type": "stream",
"text": [
- "Abundances have not been normalized to 1. - normalizing\n",
- "Zeta_data missing - replaced with 1s. Missing ions: [(12, 13), (14, 15), (16, 17), (18, 19), (20, 21)]\n",
- "/Users/archil/Documents/tardis_ayushi/tardis/plasma/properties/radiative_properties.py:93: RuntimeWarning:\n",
- "\n",
- "divide by zero encountered in true_divide\n",
- "\n",
"/Users/archil/Documents/tardis_ayushi/tardis/plasma/properties/radiative_properties.py:93: RuntimeWarning:\n",
"\n",
"invalid value encountered in true_divide\n",
"\n",
"OMP: Info #276: omp_set_nested routine deprecated, please use omp_set_max_active_levels instead.\n",
- "Zeta_data missing - replaced with 1s. Missing ions: [(12, 13), (14, 15), (16, 17), (18, 19), (20, 21)]\n",
- "/Users/archil/Documents/tardis_ayushi/tardis/plasma/properties/radiative_properties.py:93: RuntimeWarning:\n",
- "\n",
- "divide by zero encountered in true_divide\n",
- "\n",
"/Users/archil/Documents/tardis_ayushi/tardis/plasma/properties/radiative_properties.py:93: RuntimeWarning:\n",
"\n",
"invalid value encountered in true_divide\n",
@@ -108,7 +97,7 @@
{
"data": {
"application/vnd.jupyter.widget-view+json": {
- "model_id": "66c4ca69e4a34c90a0d72175c1b623e2",
+ "model_id": "d8eb291dba064c31b3c5dbe5a4b6cbb1",
"version_major": 2,
"version_minor": 0
},
@@ -122,7 +111,7 @@
{
"data": {
"application/vnd.jupyter.widget-view+json": {
- "model_id": "ecc572232c574f1cb4f951a51cc7b067",
+ "model_id": "4bf3ff0778044dc8bba920ed1f17882a",
"version_major": 2,
"version_minor": 0
},
@@ -137,39 +126,39 @@
"data": {
"text/html": [
" Shell No. | t_rad | next_t_rad | w | next_w |
\n",
+ " Shell No. | t_rad | next_t_rad | w | next_w |
\n",
" \n",
- " 0 | \n",
- " 9.93e+03 | \n",
- " 1.01e+04 | \n",
- " 0.4 | \n",
- " 0.525 | \n",
+ " 0 | \n",
+ " 9.93e+03 | \n",
+ " 1.01e+04 | \n",
+ " 0.4 | \n",
+ " 0.507 | \n",
"
\n",
" \n",
- " 5 | \n",
- " 9.85e+03 | \n",
- " 1.03e+04 | \n",
- " 0.211 | \n",
- " 0.196 | \n",
+ " 5 | \n",
+ " 9.85e+03 | \n",
+ " 1.02e+04 | \n",
+ " 0.211 | \n",
+ " 0.197 | \n",
"
\n",
" \n",
- " 10 | \n",
- " 9.78e+03 | \n",
- " 1.02e+04 | \n",
- " 0.143 | \n",
- " 0.115 | \n",
+ " 10 | \n",
+ " 9.78e+03 | \n",
+ " 1.01e+04 | \n",
+ " 0.143 | \n",
+ " 0.117 | \n",
"
\n",
" \n",
- " 15 | \n",
- " 9.71e+03 | \n",
- " 9.88e+03 | \n",
- " 0.105 | \n",
- " 0.0843 | \n",
+ " 15 | \n",
+ " 9.71e+03 | \n",
+ " 9.87e+03 | \n",
+ " 0.105 | \n",
+ " 0.0869 | \n",
"
\n",
"
"
],
"text/plain": [
- ""
+ ""
]
},
"metadata": {},
@@ -179,10 +168,6 @@
"name": "stderr",
"output_type": "stream",
"text": [
- "/Users/archil/Documents/tardis_ayushi/tardis/plasma/properties/radiative_properties.py:93: RuntimeWarning:\n",
- "\n",
- "divide by zero encountered in true_divide\n",
- "\n",
"/Users/archil/Documents/tardis_ayushi/tardis/plasma/properties/radiative_properties.py:93: RuntimeWarning:\n",
"\n",
"invalid value encountered in true_divide\n",
@@ -192,13 +177,13 @@
{
"data": {
"application/vnd.jupyter.widget-view+json": {
- "model_id": "a649a405332c41c6b0f2069e25b282b9",
+ "model_id": "406c27aae2874c609f30d917190d49b1",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"VBox(children=(FigureWidget({\n",
- " 'data': [{'type': 'scatter', 'uid': '0ae55c4d-f0da-4cbd-8121-c5c2bf1fea1b', …"
+ " 'data': [{'type': 'scatter', 'uid': '1c09c852-9039-4ca0-b150-1b5f68990ccc', …"
]
},
"metadata": {},
@@ -208,39 +193,39 @@
"data": {
"text/html": [
" Shell No. | t_rad | next_t_rad | w | next_w |
\n",
+ " Shell No. | t_rad | next_t_rad | w | next_w |
\n",
" \n",
- " 0 | \n",
- " 1.01e+04 | \n",
- " 1.1e+04 | \n",
- " 0.525 | \n",
- " 0.544 | \n",
+ " 0 | \n",
+ " 1.01e+04 | \n",
+ " 1.08e+04 | \n",
+ " 0.507 | \n",
+ " 0.525 | \n",
"
\n",
" \n",
- " 5 | \n",
- " 1.03e+04 | \n",
- " 1.11e+04 | \n",
- " 0.196 | \n",
- " 0.204 | \n",
+ " 5 | \n",
+ " 1.02e+04 | \n",
+ " 1.1e+04 | \n",
+ " 0.197 | \n",
+ " 0.203 | \n",
"
\n",
" \n",
- " 10 | \n",
- " 1.02e+04 | \n",
- " 1.08e+04 | \n",
- " 0.115 | \n",
- " 0.125 | \n",
+ " 10 | \n",
+ " 1.01e+04 | \n",
+ " 1.08e+04 | \n",
+ " 0.117 | \n",
+ " 0.125 | \n",
"
\n",
" \n",
- " 15 | \n",
- " 9.88e+03 | \n",
- " 1.06e+04 | \n",
- " 0.0843 | \n",
- " 0.0914 | \n",
+ " 15 | \n",
+ " 9.87e+03 | \n",
+ " 1.05e+04 | \n",
+ " 0.0869 | \n",
+ " 0.0933 | \n",
"
\n",
"
"
],
"text/plain": [
- ""
+ ""
]
},
"metadata": {},
@@ -250,10 +235,6 @@
"name": "stderr",
"output_type": "stream",
"text": [
- "/Users/archil/Documents/tardis_ayushi/tardis/plasma/properties/radiative_properties.py:93: RuntimeWarning:\n",
- "\n",
- "divide by zero encountered in true_divide\n",
- "\n",
"/Users/archil/Documents/tardis_ayushi/tardis/plasma/properties/radiative_properties.py:93: RuntimeWarning:\n",
"\n",
"invalid value encountered in true_divide\n",
@@ -264,39 +245,39 @@
"data": {
"text/html": [
" Shell No. | t_rad | next_t_rad | w | next_w |
\n",
+ " Shell No. | t_rad | next_t_rad | w | next_w |
\n",
" \n",
- " 0 | \n",
- " 1.1e+04 | \n",
- " 1.11e+04 | \n",
- " 0.544 | \n",
- " 0.501 | \n",
+ " 0 | \n",
+ " 1.08e+04 | \n",
+ " 1.1e+04 | \n",
+ " 0.525 | \n",
+ " 0.483 | \n",
"
\n",
" \n",
- " 5 | \n",
- " 1.11e+04 | \n",
- " 1.14e+04 | \n",
- " 0.204 | \n",
- " 0.185 | \n",
+ " 5 | \n",
+ " 1.1e+04 | \n",
+ " 1.12e+04 | \n",
+ " 0.203 | \n",
+ " 0.189 | \n",
"
\n",
" \n",
- " 10 | \n",
- " 1.08e+04 | \n",
- " 1.11e+04 | \n",
- " 0.125 | \n",
- " 0.115 | \n",
+ " 10 | \n",
+ " 1.08e+04 | \n",
+ " 1.1e+04 | \n",
+ " 0.125 | \n",
+ " 0.118 | \n",
"
\n",
" \n",
- " 15 | \n",
- " 1.06e+04 | \n",
- " 1.08e+04 | \n",
- " 0.0914 | \n",
- " 0.086 | \n",
+ " 15 | \n",
+ " 1.05e+04 | \n",
+ " 1.06e+04 | \n",
+ " 0.0933 | \n",
+ " 0.0895 | \n",
"
\n",
"
"
],
"text/plain": [
- ""
+ ""
]
},
"metadata": {},
@@ -306,39 +287,39 @@
"data": {
"text/html": [
" Shell No. | t_rad | next_t_rad | w | next_w |
\n",
+ " Shell No. | t_rad | next_t_rad | w | next_w |
\n",
" \n",
- " 0 | \n",
- " 1.11e+04 | \n",
- " 1.11e+04 | \n",
- " 0.501 | \n",
- " 0.487 | \n",
+ " 0 | \n",
+ " 1.1e+04 | \n",
+ " 1.1e+04 | \n",
+ " 0.483 | \n",
+ " 0.469 | \n",
"
\n",
" \n",
- " 5 | \n",
- " 1.14e+04 | \n",
- " 1.14e+04 | \n",
- " 0.185 | \n",
- " 0.181 | \n",
+ " 5 | \n",
+ " 1.12e+04 | \n",
+ " 1.12e+04 | \n",
+ " 0.189 | \n",
+ " 0.182 | \n",
"
\n",
" \n",
- " 10 | \n",
- " 1.11e+04 | \n",
- " 1.11e+04 | \n",
- " 0.115 | \n",
- " 0.112 | \n",
+ " 10 | \n",
+ " 1.1e+04 | \n",
+ " 1.1e+04 | \n",
+ " 0.118 | \n",
+ " 0.113 | \n",
"
\n",
" \n",
- " 15 | \n",
- " 1.08e+04 | \n",
- " 1.08e+04 | \n",
- " 0.086 | \n",
- " 0.0819 | \n",
+ " 15 | \n",
+ " 1.06e+04 | \n",
+ " 1.07e+04 | \n",
+ " 0.0895 | \n",
+ " 0.0861 | \n",
"
\n",
"
"
],
"text/plain": [
- ""
+ ""
]
},
"metadata": {},
@@ -348,39 +329,39 @@
"data": {
"text/html": [
" Shell No. | t_rad | next_t_rad | w | next_w |
\n",
+ " Shell No. | t_rad | next_t_rad | w | next_w |
\n",
" \n",
- " 0 | \n",
- " 1.11e+04 | \n",
- " 1.11e+04 | \n",
- " 0.487 | \n",
- " 0.497 | \n",
+ " 0 | \n",
+ " 1.1e+04 | \n",
+ " 1.1e+04 | \n",
+ " 0.469 | \n",
+ " 0.479 | \n",
"
\n",
" \n",
- " 5 | \n",
- " 1.14e+04 | \n",
- " 1.14e+04 | \n",
- " 0.181 | \n",
- " 0.178 | \n",
+ " 5 | \n",
+ " 1.12e+04 | \n",
+ " 1.13e+04 | \n",
+ " 0.182 | \n",
+ " 0.178 | \n",
"
\n",
" \n",
- " 10 | \n",
- " 1.11e+04 | \n",
- " 1.13e+04 | \n",
- " 0.112 | \n",
- " 0.107 | \n",
+ " 10 | \n",
+ " 1.1e+04 | \n",
+ " 1.1e+04 | \n",
+ " 0.113 | \n",
+ " 0.113 | \n",
"
\n",
" \n",
- " 15 | \n",
- " 1.08e+04 | \n",
- " 1.1e+04 | \n",
- " 0.0819 | \n",
- " 0.0779 | \n",
+ " 15 | \n",
+ " 1.07e+04 | \n",
+ " 1.07e+04 | \n",
+ " 0.0861 | \n",
+ " 0.0839 | \n",
"
\n",
"
"
],
"text/plain": [
- ""
+ ""
]
},
"metadata": {},
@@ -390,39 +371,39 @@
"data": {
"text/html": [
" Shell No. | t_rad | next_t_rad | w | next_w |
\n",
+ " Shell No. | t_rad | next_t_rad | w | next_w |
\n",
" \n",
- " 0 | \n",
- " 1.11e+04 | \n",
- " 1.12e+04 | \n",
- " 0.497 | \n",
- " 0.488 | \n",
+ " 0 | \n",
+ " 1.1e+04 | \n",
+ " 1.1e+04 | \n",
+ " 0.479 | \n",
+ " 0.47 | \n",
"
\n",
" \n",
- " 5 | \n",
- " 1.14e+04 | \n",
- " 1.14e+04 | \n",
- " 0.178 | \n",
- " 0.184 | \n",
+ " 5 | \n",
+ " 1.13e+04 | \n",
+ " 1.12e+04 | \n",
+ " 0.178 | \n",
+ " 0.185 | \n",
"
\n",
" \n",
- " 10 | \n",
- " 1.13e+04 | \n",
- " 1.11e+04 | \n",
- " 0.107 | \n",
- " 0.113 | \n",
+ " 10 | \n",
+ " 1.1e+04 | \n",
+ " 1.11e+04 | \n",
+ " 0.113 | \n",
+ " 0.112 | \n",
"
\n",
" \n",
- " 15 | \n",
- " 1.1e+04 | \n",
- " 1.08e+04 | \n",
- " 0.0779 | \n",
- " 0.082 | \n",
+ " 15 | \n",
+ " 1.07e+04 | \n",
+ " 1.07e+04 | \n",
+ " 0.0839 | \n",
+ " 0.0856 | \n",
"
\n",
"
"
],
"text/plain": [
- ""
+ ""
]
},
"metadata": {},
@@ -432,39 +413,39 @@
"data": {
"text/html": [
" Shell No. | t_rad | next_t_rad | w | next_w |
\n",
+ " Shell No. | t_rad | next_t_rad | w | next_w |
\n",
" \n",
- " 0 | \n",
- " 1.12e+04 | \n",
- " 1.11e+04 | \n",
- " 0.488 | \n",
- " 0.496 | \n",
+ " 0 | \n",
+ " 1.1e+04 | \n",
+ " 1.1e+04 | \n",
+ " 0.47 | \n",
+ " 0.47 | \n",
"
\n",
" \n",
- " 5 | \n",
- " 1.14e+04 | \n",
- " 1.15e+04 | \n",
- " 0.184 | \n",
- " 0.175 | \n",
+ " 5 | \n",
+ " 1.12e+04 | \n",
+ " 1.13e+04 | \n",
+ " 0.185 | \n",
+ " 0.178 | \n",
"
\n",
" \n",
- " 10 | \n",
- " 1.11e+04 | \n",
- " 1.12e+04 | \n",
- " 0.113 | \n",
- " 0.109 | \n",
+ " 10 | \n",
+ " 1.11e+04 | \n",
+ " 1.11e+04 | \n",
+ " 0.112 | \n",
+ " 0.112 | \n",
"
\n",
" \n",
- " 15 | \n",
- " 1.08e+04 | \n",
- " 1.09e+04 | \n",
- " 0.082 | \n",
- " 0.0816 | \n",
+ " 15 | \n",
+ " 1.07e+04 | \n",
+ " 1.07e+04 | \n",
+ " 0.0856 | \n",
+ " 0.086 | \n",
"
\n",
"
"
],
"text/plain": [
- ""
+ ""
]
},
"metadata": {},
@@ -474,39 +455,39 @@
"data": {
"text/html": [
" Shell No. | t_rad | next_t_rad | w | next_w |
\n",
+ " Shell No. | t_rad | next_t_rad | w | next_w |
\n",
" \n",
- " 0 | \n",
- " 1.11e+04 | \n",
- " 1.12e+04 | \n",
- " 0.496 | \n",
- " 0.49 | \n",
+ " 0 | \n",
+ " 1.1e+04 | \n",
+ " 1.11e+04 | \n",
+ " 0.47 | \n",
+ " 0.472 | \n",
"
\n",
" \n",
- " 5 | \n",
- " 1.15e+04 | \n",
- " 1.16e+04 | \n",
- " 0.175 | \n",
- " 0.174 | \n",
+ " 5 | \n",
+ " 1.13e+04 | \n",
+ " 1.14e+04 | \n",
+ " 0.178 | \n",
+ " 0.175 | \n",
"
\n",
" \n",
- " 10 | \n",
- " 1.12e+04 | \n",
- " 1.14e+04 | \n",
- " 0.109 | \n",
- " 0.106 | \n",
+ " 10 | \n",
+ " 1.11e+04 | \n",
+ " 1.11e+04 | \n",
+ " 0.112 | \n",
+ " 0.111 | \n",
"
\n",
" \n",
- " 15 | \n",
- " 1.09e+04 | \n",
- " 1.09e+04 | \n",
- " 0.0816 | \n",
- " 0.0802 | \n",
+ " 15 | \n",
+ " 1.07e+04 | \n",
+ " 1.07e+04 | \n",
+ " 0.086 | \n",
+ " 0.084 | \n",
"
\n",
"
"
],
"text/plain": [
- ""
+ ""
]
},
"metadata": {},
@@ -516,39 +497,39 @@
"data": {
"text/html": [
" Shell No. | t_rad | next_t_rad | w | next_w |
\n",
+ " Shell No. | t_rad | next_t_rad | w | next_w |
\n",
" \n",
- " 0 | \n",
- " 1.12e+04 | \n",
- " 1.11e+04 | \n",
- " 0.49 | \n",
- " 0.49 | \n",
+ " 0 | \n",
+ " 1.11e+04 | \n",
+ " 1.11e+04 | \n",
+ " 0.472 | \n",
+ " 0.469 | \n",
"
\n",
" \n",
- " 5 | \n",
- " 1.16e+04 | \n",
- " 1.15e+04 | \n",
- " 0.174 | \n",
- " 0.174 | \n",
+ " 5 | \n",
+ " 1.14e+04 | \n",
+ " 1.15e+04 | \n",
+ " 0.175 | \n",
+ " 0.17 | \n",
"
\n",
" \n",
- " 10 | \n",
- " 1.14e+04 | \n",
- " 1.13e+04 | \n",
- " 0.106 | \n",
- " 0.104 | \n",
+ " 10 | \n",
+ " 1.11e+04 | \n",
+ " 1.11e+04 | \n",
+ " 0.111 | \n",
+ " 0.109 | \n",
"
\n",
" \n",
- " 15 | \n",
- " 1.09e+04 | \n",
- " 1.09e+04 | \n",
- " 0.0802 | \n",
- " 0.0799 | \n",
+ " 15 | \n",
+ " 1.07e+04 | \n",
+ " 1.08e+04 | \n",
+ " 0.084 | \n",
+ " 0.0822 | \n",
"
\n",
"
"
],
"text/plain": [
- ""
+ ""
]
},
"metadata": {},
@@ -558,39 +539,39 @@
"data": {
"text/html": [
" Shell No. | t_rad | next_t_rad | w | next_w |
\n",
+ " Shell No. | t_rad | next_t_rad | w | next_w |
\n",
" \n",
- " 0 | \n",
- " 1.11e+04 | \n",
- " 1.11e+04 | \n",
- " 0.49 | \n",
- " 0.496 | \n",
+ " 0 | \n",
+ " 1.11e+04 | \n",
+ " 1.1e+04 | \n",
+ " 0.469 | \n",
+ " 0.475 | \n",
"
\n",
" \n",
- " 5 | \n",
- " 1.15e+04 | \n",
- " 1.15e+04 | \n",
- " 0.174 | \n",
- " 0.177 | \n",
+ " 5 | \n",
+ " 1.15e+04 | \n",
+ " 1.14e+04 | \n",
+ " 0.17 | \n",
+ " 0.177 | \n",
"
\n",
" \n",
- " 10 | \n",
- " 1.13e+04 | \n",
- " 1.14e+04 | \n",
- " 0.104 | \n",
- " 0.105 | \n",
+ " 10 | \n",
+ " 1.11e+04 | \n",
+ " 1.11e+04 | \n",
+ " 0.109 | \n",
+ " 0.112 | \n",
"
\n",
" \n",
- " 15 | \n",
- " 1.09e+04 | \n",
- " 1.09e+04 | \n",
- " 0.0799 | \n",
- " 0.081 | \n",
+ " 15 | \n",
+ " 1.08e+04 | \n",
+ " 1.06e+04 | \n",
+ " 0.0822 | \n",
+ " 0.0878 | \n",
"
\n",
"
"
],
"text/plain": [
- ""
+ ""
]
},
"metadata": {},
@@ -600,39 +581,39 @@
"data": {
"text/html": [
" Shell No. | t_rad | next_t_rad | w | next_w |
\n",
+ " Shell No. | t_rad | next_t_rad | w | next_w |
\n",
" \n",
- " 0 | \n",
- " 1.11e+04 | \n",
- " 1.11e+04 | \n",
- " 0.496 | \n",
- " 0.501 | \n",
+ " 0 | \n",
+ " 1.1e+04 | \n",
+ " 1.1e+04 | \n",
+ " 0.475 | \n",
+ " 0.472 | \n",
"
\n",
" \n",
- " 5 | \n",
- " 1.15e+04 | \n",
- " 1.16e+04 | \n",
- " 0.177 | \n",
- " 0.174 | \n",
+ " 5 | \n",
+ " 1.14e+04 | \n",
+ " 1.12e+04 | \n",
+ " 0.177 | \n",
+ " 0.184 | \n",
"
\n",
" \n",
- " 10 | \n",
- " 1.14e+04 | \n",
- " 1.14e+04 | \n",
- " 0.105 | \n",
- " 0.104 | \n",
+ " 10 | \n",
+ " 1.11e+04 | \n",
+ " 1.1e+04 | \n",
+ " 0.112 | \n",
+ " 0.114 | \n",
"
\n",
" \n",
- " 15 | \n",
- " 1.09e+04 | \n",
- " 1.09e+04 | \n",
- " 0.081 | \n",
- " 0.0809 | \n",
+ " 15 | \n",
+ " 1.06e+04 | \n",
+ " 1.06e+04 | \n",
+ " 0.0878 | \n",
+ " 0.0859 | \n",
"
\n",
"
"
],
"text/plain": [
- ""
+ ""
]
},
"metadata": {},
@@ -642,39 +623,39 @@
"data": {
"text/html": [
" Shell No. | t_rad | next_t_rad | w | next_w |
\n",
+ " Shell No. | t_rad | next_t_rad | w | next_w |
\n",
" \n",
- " 0 | \n",
- " 1.11e+04 | \n",
- " 1.12e+04 | \n",
- " 0.501 | \n",
- " 0.485 | \n",
+ " 0 | \n",
+ " 1.1e+04 | \n",
+ " 1.11e+04 | \n",
+ " 0.472 | \n",
+ " 0.467 | \n",
"
\n",
" \n",
- " 5 | \n",
- " 1.16e+04 | \n",
- " 1.16e+04 | \n",
- " 0.174 | \n",
- " 0.17 | \n",
+ " 5 | \n",
+ " 1.12e+04 | \n",
+ " 1.13e+04 | \n",
+ " 0.184 | \n",
+ " 0.176 | \n",
"
\n",
" \n",
- " 10 | \n",
- " 1.14e+04 | \n",
- " 1.13e+04 | \n",
- " 0.104 | \n",
- " 0.105 | \n",
+ " 10 | \n",
+ " 1.1e+04 | \n",
+ " 1.11e+04 | \n",
+ " 0.114 | \n",
+ " 0.11 | \n",
"
\n",
" \n",
- " 15 | \n",
- " 1.09e+04 | \n",
- " 1.1e+04 | \n",
- " 0.0809 | \n",
- " 0.0777 | \n",
+ " 15 | \n",
+ " 1.06e+04 | \n",
+ " 1.08e+04 | \n",
+ " 0.0859 | \n",
+ " 0.0821 | \n",
"
\n",
"
"
],
"text/plain": [
- ""
+ ""
]
},
"metadata": {},
@@ -684,39 +665,39 @@
"data": {
"text/html": [
" Shell No. | t_rad | next_t_rad | w | next_w |
\n",
+ " Shell No. | t_rad | next_t_rad | w | next_w |
\n",
" \n",
- " 0 | \n",
- " 1.12e+04 | \n",
- " 1.12e+04 | \n",
- " 0.485 | \n",
- " 0.483 | \n",
+ " 0 | \n",
+ " 1.11e+04 | \n",
+ " 1.11e+04 | \n",
+ " 0.467 | \n",
+ " 0.466 | \n",
"
\n",
" \n",
- " 5 | \n",
- " 1.16e+04 | \n",
- " 1.16e+04 | \n",
- " 0.17 | \n",
- " 0.174 | \n",
+ " 5 | \n",
+ " 1.13e+04 | \n",
+ " 1.13e+04 | \n",
+ " 0.176 | \n",
+ " 0.18 | \n",
"
\n",
" \n",
- " 10 | \n",
- " 1.13e+04 | \n",
- " 1.14e+04 | \n",
- " 0.105 | \n",
- " 0.105 | \n",
+ " 10 | \n",
+ " 1.11e+04 | \n",
+ " 1.11e+04 | \n",
+ " 0.11 | \n",
+ " 0.111 | \n",
"
\n",
" \n",
- " 15 | \n",
- " 1.1e+04 | \n",
- " 1.1e+04 | \n",
- " 0.0777 | \n",
- " 0.0789 | \n",
+ " 15 | \n",
+ " 1.08e+04 | \n",
+ " 1.08e+04 | \n",
+ " 0.0821 | \n",
+ " 0.0841 | \n",
"
\n",
"
"
],
"text/plain": [
- ""
+ ""
]
},
"metadata": {},
@@ -726,39 +707,39 @@
"data": {
"text/html": [
" Shell No. | t_rad | next_t_rad | w | next_w |
\n",
+ " Shell No. | t_rad | next_t_rad | w | next_w |
\n",
" \n",
- " 0 | \n",
- " 1.12e+04 | \n",
- " 1.12e+04 | \n",
- " 0.483 | \n",
- " 0.48 | \n",
+ " 0 | \n",
+ " 1.11e+04 | \n",
+ " 1.11e+04 | \n",
+ " 0.466 | \n",
+ " 0.469 | \n",
"
\n",
" \n",
- " 5 | \n",
- " 1.16e+04 | \n",
- " 1.16e+04 | \n",
- " 0.174 | \n",
- " 0.174 | \n",
+ " 5 | \n",
+ " 1.13e+04 | \n",
+ " 1.13e+04 | \n",
+ " 0.18 | \n",
+ " 0.182 | \n",
"
\n",
" \n",
- " 10 | \n",
- " 1.14e+04 | \n",
- " 1.13e+04 | \n",
- " 0.105 | \n",
- " 0.105 | \n",
+ " 10 | \n",
+ " 1.11e+04 | \n",
+ " 1.1e+04 | \n",
+ " 0.111 | \n",
+ " 0.113 | \n",
"
\n",
" \n",
- " 15 | \n",
- " 1.1e+04 | \n",
- " 1.09e+04 | \n",
- " 0.0789 | \n",
- " 0.0789 | \n",
+ " 15 | \n",
+ " 1.08e+04 | \n",
+ " 1.07e+04 | \n",
+ " 0.0841 | \n",
+ " 0.0854 | \n",
"
\n",
"
"
],
"text/plain": [
- ""
+ ""
]
},
"metadata": {},
@@ -768,39 +749,39 @@
"data": {
"text/html": [
" Shell No. | t_rad | next_t_rad | w | next_w |
\n",
+ " Shell No. | t_rad | next_t_rad | w | next_w |
\n",
" \n",
- " 0 | \n",
- " 1.12e+04 | \n",
- " 1.12e+04 | \n",
- " 0.48 | \n",
- " 0.486 | \n",
+ " 0 | \n",
+ " 1.11e+04 | \n",
+ " 1.1e+04 | \n",
+ " 0.469 | \n",
+ " 0.484 | \n",
"
\n",
" \n",
- " 5 | \n",
- " 1.16e+04 | \n",
- " 1.15e+04 | \n",
- " 0.174 | \n",
- " 0.18 | \n",
+ " 5 | \n",
+ " 1.13e+04 | \n",
+ " 1.13e+04 | \n",
+ " 0.182 | \n",
+ " 0.181 | \n",
"
\n",
" \n",
- " 10 | \n",
- " 1.13e+04 | \n",
- " 1.12e+04 | \n",
- " 0.105 | \n",
- " 0.108 | \n",
+ " 10 | \n",
+ " 1.1e+04 | \n",
+ " 1.1e+04 | \n",
+ " 0.113 | \n",
+ " 0.113 | \n",
"
\n",
" \n",
- " 15 | \n",
- " 1.09e+04 | \n",
- " 1.09e+04 | \n",
- " 0.0789 | \n",
- " 0.0793 | \n",
+ " 15 | \n",
+ " 1.07e+04 | \n",
+ " 1.07e+04 | \n",
+ " 0.0854 | \n",
+ " 0.0858 | \n",
"
\n",
"
"
],
"text/plain": [
- ""
+ ""
]
},
"metadata": {},
@@ -810,39 +791,39 @@
"data": {
"text/html": [
" Shell No. | t_rad | next_t_rad | w | next_w |
\n",
+ " Shell No. | t_rad | next_t_rad | w | next_w |
\n",
" \n",
- " 0 | \n",
- " 1.12e+04 | \n",
- " 1.12e+04 | \n",
- " 0.486 | \n",
- " 0.486 | \n",
+ " 0 | \n",
+ " 1.1e+04 | \n",
+ " 1.1e+04 | \n",
+ " 0.484 | \n",
+ " 0.472 | \n",
"
\n",
" \n",
- " 5 | \n",
- " 1.15e+04 | \n",
- " 1.15e+04 | \n",
- " 0.18 | \n",
- " 0.177 | \n",
+ " 5 | \n",
+ " 1.13e+04 | \n",
+ " 1.13e+04 | \n",
+ " 0.181 | \n",
+ " 0.177 | \n",
"
\n",
" \n",
- " 10 | \n",
- " 1.12e+04 | \n",
- " 1.13e+04 | \n",
- " 0.108 | \n",
- " 0.107 | \n",
+ " 10 | \n",
+ " 1.1e+04 | \n",
+ " 1.1e+04 | \n",
+ " 0.113 | \n",
+ " 0.113 | \n",
"
\n",
" \n",
- " 15 | \n",
- " 1.09e+04 | \n",
- " 1.09e+04 | \n",
- " 0.0793 | \n",
- " 0.0811 | \n",
+ " 15 | \n",
+ " 1.07e+04 | \n",
+ " 1.06e+04 | \n",
+ " 0.0858 | \n",
+ " 0.0858 | \n",
"
\n",
"
"
],
"text/plain": [
- ""
+ ""
]
},
"metadata": {},
@@ -852,39 +833,39 @@
"data": {
"text/html": [
" Shell No. | t_rad | next_t_rad | w | next_w |
\n",
+ " Shell No. | t_rad | next_t_rad | w | next_w |
\n",
" \n",
- " 0 | \n",
- " 1.12e+04 | \n",
- " 1.12e+04 | \n",
- " 0.486 | \n",
- " 0.483 | \n",
+ " 0 | \n",
+ " 1.1e+04 | \n",
+ " 1.11e+04 | \n",
+ " 0.472 | \n",
+ " 0.468 | \n",
"
\n",
" \n",
- " 5 | \n",
- " 1.15e+04 | \n",
- " 1.16e+04 | \n",
- " 0.177 | \n",
- " 0.17 | \n",
+ " 5 | \n",
+ " 1.13e+04 | \n",
+ " 1.14e+04 | \n",
+ " 0.177 | \n",
+ " 0.175 | \n",
"
\n",
" \n",
- " 10 | \n",
- " 1.13e+04 | \n",
- " 1.13e+04 | \n",
- " 0.107 | \n",
- " 0.107 | \n",
+ " 10 | \n",
+ " 1.1e+04 | \n",
+ " 1.11e+04 | \n",
+ " 0.113 | \n",
+ " 0.11 | \n",
"
\n",
" \n",
- " 15 | \n",
- " 1.09e+04 | \n",
- " 1.09e+04 | \n",
- " 0.0811 | \n",
- " 0.0799 | \n",
+ " 15 | \n",
+ " 1.06e+04 | \n",
+ " 1.08e+04 | \n",
+ " 0.0858 | \n",
+ " 0.0816 | \n",
"
\n",
"
"
],
"text/plain": [
- ""
+ ""
]
},
"metadata": {},
@@ -894,39 +875,39 @@
"data": {
"text/html": [
" Shell No. | t_rad | next_t_rad | w | next_w |
\n",
+ " Shell No. | t_rad | next_t_rad | w | next_w |
\n",
" \n",
- " 0 | \n",
- " 1.12e+04 | \n",
- " 1.12e+04 | \n",
- " 0.483 | \n",
- " 0.482 | \n",
+ " 0 | \n",
+ " 1.11e+04 | \n",
+ " 1.11e+04 | \n",
+ " 0.468 | \n",
+ " 0.464 | \n",
"
\n",
" \n",
- " 5 | \n",
- " 1.16e+04 | \n",
- " 1.16e+04 | \n",
- " 0.17 | \n",
- " 0.172 | \n",
+ " 5 | \n",
+ " 1.14e+04 | \n",
+ " 1.13e+04 | \n",
+ " 0.175 | \n",
+ " 0.177 | \n",
"
\n",
" \n",
- " 10 | \n",
- " 1.13e+04 | \n",
- " 1.13e+04 | \n",
- " 0.107 | \n",
- " 0.105 | \n",
+ " 10 | \n",
+ " 1.11e+04 | \n",
+ " 1.1e+04 | \n",
+ " 0.11 | \n",
+ " 0.113 | \n",
"
\n",
" \n",
- " 15 | \n",
- " 1.09e+04 | \n",
- " 1.09e+04 | \n",
- " 0.0799 | \n",
- " 0.0807 | \n",
+ " 15 | \n",
+ " 1.08e+04 | \n",
+ " 1.07e+04 | \n",
+ " 0.0816 | \n",
+ " 0.0848 | \n",
"
\n",
"
"
],
"text/plain": [
- ""
+ ""
]
},
"metadata": {},
@@ -936,39 +917,39 @@
"data": {
"text/html": [
" Shell No. | t_rad | next_t_rad | w | next_w |
\n",
+ " Shell No. | t_rad | next_t_rad | w | next_w |
\n",
" \n",
- " 0 | \n",
- " 1.12e+04 | \n",
- " 1.12e+04 | \n",
- " 0.482 | \n",
- " 0.478 | \n",
+ " 0 | \n",
+ " 1.11e+04 | \n",
+ " 1.11e+04 | \n",
+ " 0.464 | \n",
+ " 0.466 | \n",
"
\n",
" \n",
- " 5 | \n",
- " 1.16e+04 | \n",
- " 1.14e+04 | \n",
- " 0.172 | \n",
- " 0.177 | \n",
+ " 5 | \n",
+ " 1.13e+04 | \n",
+ " 1.13e+04 | \n",
+ " 0.177 | \n",
+ " 0.177 | \n",
"
\n",
" \n",
- " 10 | \n",
- " 1.13e+04 | \n",
- " 1.13e+04 | \n",
- " 0.105 | \n",
- " 0.107 | \n",
+ " 10 | \n",
+ " 1.1e+04 | \n",
+ " 1.11e+04 | \n",
+ " 0.113 | \n",
+ " 0.111 | \n",
"
\n",
" \n",
- " 15 | \n",
- " 1.09e+04 | \n",
- " 1.08e+04 | \n",
- " 0.0807 | \n",
- " 0.0814 | \n",
+ " 15 | \n",
+ " 1.07e+04 | \n",
+ " 1.07e+04 | \n",
+ " 0.0848 | \n",
+ " 0.0853 | \n",
"
\n",
"
"
],
"text/plain": [
- ""
+ ""
]
},
"metadata": {},
@@ -983,349 +964,29 @@
")\n",
"model = SimulationState.from_config(config, atom_data=atom_data)\n",
"plasma = assemble_plasma(config, model, atom_data=atom_data)\n",
- "sim = Simulation.from_config(config, model=model, plasma=plasma)\n",
+ "sim = Simulation.from_config(\n",
+ " config, model=model, plasma=plasma, atom_data=atom_data\n",
+ ")\n",
"sim.run_convergence()\n",
"sim.run_final()"
]
},
- {
- "cell_type": "code",
- "execution_count": 3,
- "metadata": {
- "scrolled": false
- },
- "outputs": [
- {
- "name": "stderr",
- "output_type": "stream",
- "text": [
- "/Users/archil/miniforge3/envs/tardis/lib/python3.8/site-packages/pandas/core/series.py:679: RuntimeWarning:\n",
- "\n",
- "divide by zero encountered in log\n",
- "\n"
- ]
- },
- {
- "data": {
- "text/html": [
- " \n",
- " "
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- },
- {
- "data": {
- "text/html": [
- ""
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- }
- ],
- "source": [
- "diag = GrotrianWidget.from_simulation(sim)\n",
- "diag.set_ion(2, 0) # He I\n",
- "diag.display()"
- ]
- },
{
"cell_type": "code",
"execution_count": 4,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/html": [
- ""
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- }
- ],
- "source": [
- "# Change color scale\n",
- "diag.cmapname = \"viridis\"\n",
- "diag.display()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 5,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/html": [
- ""
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- }
- ],
- "source": [
- "diag.shell = 6\n",
- "diag.display()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 6,
"metadata": {
"scrolled": false
},
"outputs": [
{
"data": {
- "text/html": [
- ""
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- }
- ],
- "source": [
- "diag = GrotrianWidget.from_simulation(sim)\n",
- "diag.set_ion(8, 0) # O I\n",
- "diag.display()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 7,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/html": [
- ""
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- }
- ],
- "source": [
- "diag.shell = 0\n",
- "diag.display()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 8,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/html": [
- ""
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- }
- ],
- "source": [
- "diag.y_scale = \"Log\"\n",
- "diag.display()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 9,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/html": [
- ""
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "c91528c218b440f7912a8f3a8674e48e",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "VBox(children=(HBox(children=(Dropdown(description='Ion', options=('O I', 'O II', 'O III', 'Mg II', 'Si II', '…"
]
},
"metadata": {},
@@ -1334,74 +995,9 @@
],
"source": [
"diag = GrotrianWidget.from_simulation(sim)\n",
- "diag.set_ion(14, 1) # Si II\n",
"diag.display()"
]
},
- {
- "cell_type": "code",
- "execution_count": 10,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/html": [
- ""
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- }
- ],
- "source": [
- "diag.shell = 5\n",
- "diag.display()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 11,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "array([ 6, 0, -1, ..., -1, -1, -1])"
- ]
- },
- "execution_count": 11,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "sim.transport.last_line_interaction_shell_id"
- ]
- },
{
"cell_type": "code",
"execution_count": null,
@@ -1426,7 +1022,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
- "version": "3.8.16"
+ "version": "3.11.5"
}
},
"nbformat": 4,