You can interact with this notebook online: Launch notebook
How to Run TARDIS Model Grids¶
This notebook demonstrates the capabilities of the TARDIS grid. The grid facilitates users running large numbers of TARDIS simulations.
[1]:
import pandas as pd
import numpy as np
from tardis.io.atom_data import download_atom_data
from tardis.io.atom_data import AtomData
import tardis.grid as grid
[2]:
# We download the atomic data needed to run a TARDIS simulation
download_atom_data('kurucz_cd23_chianti_H_He')
Atomic Data kurucz_cd23_chianti_H_He already exists in /home/runner/Downloads/tardis-data/kurucz_cd23_chianti_H_He.h5. Will not download - override with force_download=True.
Creating A Grid¶
There are 2 ways of creating a TARDIS grid: directly from a dataframe, or by defining a set of axes over which the grid should be defined. In both cases, a config.yml file is required. Note that for the dataframe, the column names are in the form of valid keys in a tardis Configuration dictionary. For the axes, the keys must similarly be valid tardis Configuration keys.
[3]:
# Load a DataFrame
df = pd.read_csv('example_grid.txt')
df
[3]:
model.abundances.H | model.abundances.He | model.structure.velocity.start | plasma.initial_t_inner | |
---|---|---|---|---|
0 | 1.0 | 0.0 | 10000 | 5000 |
1 | 0.4 | 0.6 | 12000 | 6000 |
2 | 0.7 | 0.3 | 15000 | 7000 |
[4]:
# Create a tardis grid directly from a dataframe.
grid.tardisGrid(configFile='example.yml', gridFrame=df)
[4]:
<tardis.grid.base.tardisGrid at 0x7fcaae268680>
[5]:
# Create an axes dictionary
axesdict = {'model.structure.velocity.start':np.arange(10000,15000,1000),
'model.abundances.He':np.arange(0,1,0.1),
'model.abundances.H':np.arange(0,1,0.25)}
[6]:
#Create a tardis grid from an axes dict using the classmethod.
grid.tardisGrid.from_axes(configFile='example.yml', axesdict=axesdict)
[6]:
<tardis.grid.base.tardisGrid at 0x7fcb08eeede0>
TARDIS Grid Attributes¶
The TARDIS grid only has 2 attributes. It creates a TARDIS Configuration object from the user specified config.yml file and saves this to the self.config
attribute. The grid also stores the parameters of every grid point in a Dataframe accessed by self.grid
[7]:
tg = grid.tardisGrid(configFile='example.yml', gridFrame=df)
[8]:
# The config generated from the user's yml file.
tg.config
[8]:
{'tardis_config_version': 'v1.0',
'supernova': {'luminosity_requested': <Quantity 5.679e+41 erg / s>,
'luminosity_wavelength_start': <Quantity 3481.82000178 Angstrom>,
'luminosity_wavelength_end': <Quantity 9947.78776065 Angstrom>,
'time_explosion': <Quantity 10. d>},
'atom_data': 'kurucz_cd23_chianti_H_He.h5',
'model': {'structure': {'type': 'specific',
'velocity': {'start': <Quantity 10000. km / s>,
'stop': <Quantity 20000. km / s>,
'num': 20},
'density': {'type': 'branch85_w7',
'w7_time_0': <Quantity 0.00023148 d>,
'w7_rho_0': <Quantity 3.e+29 g / cm3>,
'w7_v_0': <Quantity 1. km / s>}},
'abundances': {'type': 'uniform',
'He': 0.2,
'H': 0.8,
'model_isotope_time_0': <Quantity 0. s>}},
'plasma': {'initial_t_inner': <Quantity 7000. K>,
'disable_electron_scattering': False,
'ionization': 'nebular',
'excitation': 'dilute-lte',
'radiative_rates_type': 'dilute-blackbody',
'line_interaction_type': 'macroatom',
'initial_t_rad': <Quantity -1. K>,
'disable_line_scattering': False,
'w_epsilon': 1e-10,
'nlte': {'species': [],
'coronal_approximation': False,
'classical_nebular': False},
'continuum_interaction': {'species': [],
'enable_adiabatic_cooling': False,
'enable_two_photon_decay': False},
'helium_treatment': 'none',
'heating_rate_data_file': 'none',
'link_t_rad_t_electron': 0.9,
'nlte_ionization_species': [],
'nlte_excitation_species': [],
'nlte_solver': 'root'},
'montecarlo': {'seed': 23111963,
'no_of_packets': 40000.0,
'iterations': 2,
'nthreads': 1,
'last_no_of_packets': 1000.0,
'no_of_virtual_packets': 3,
'convergence_strategy': {'type': 'damped',
'damping_constant': 0.5,
'threshold': 0.05,
'fraction': 0.8,
'hold_iterations': 3,
't_inner': {'damping_constant': 0.5, 'type': 'damped', 'threshold': 0.05},
'stop_if_converged': False,
'lock_t_inner_cycles': 1,
't_inner_update_exponent': -0.5,
't_rad': {'damping_constant': 0.5, 'threshold': 0.05, 'type': 'damped'},
'w': {'damping_constant': 0.5, 'threshold': 0.05, 'type': 'damped'}},
'virtual_spectrum_spawn_range': {'start': <Quantity 1. Angstrom>,
'end': <Quantity inf Angstrom>},
'enable_full_relativity': False,
'enable_nonhomologous_expansion': False,
'tracking': {'track_rpacket': False, 'initial_array_length': 10},
'debug_packets': False,
'logger_buffer': 1},
'spectrum': {'start': <Quantity 500. Angstrom>,
'stop': <Quantity 20000. Angstrom>,
'num': 10000,
'method': 'virtual',
'integrated': {'points': 1000, 'interpolate_shells': 0, 'compute': 'CPU'},
'virtual': {'tau_russian': 10.0,
'survival_probability': 0.0,
'enable_biasing': False,
'virtual_packet_logging': False}},
'config_dirname': ''}
[9]:
# The user specified grid.
tg.grid
[9]:
model.abundances.H | model.abundances.He | model.structure.velocity.start | plasma.initial_t_inner | |
---|---|---|---|---|
0 | 1.0 | 0.0 | 10000 | 5000 |
1 | 0.4 | 0.6 | 12000 | 6000 |
2 | 0.7 | 0.3 | 15000 | 7000 |
TARDIS Grid Functionality¶
The TARDIS Grid provides a variety of functions for using the grid to generate new Configurations, return new SimulationState objects, or directly run simulations using the parameters specified by the grid. This functionality is particularly useful for running large numbers of simulations and easily works with JobArrays where the row_index is the JobArray index.
[10]:
# Easily get a new TARDIS Configuration object
# which has the properties of the base self.config
# but with properties modified by a row of the grid.
new_grid = tg.grid_row_to_config(row_index=0);
print("tg.config is the original config:",tg.config.model.abundances)
print("The new config is modified: ",new_grid.model.abundances)
tg.config is the original config: {'type': 'uniform', 'He': 0.2, 'H': 0.8, 'model_isotope_time_0': <Quantity 0. s>}
The new config is modified: {'type': 'uniform', 'He': 0.0, 'H': 1.0, 'model_isotope_time_0': <Quantity 0. s>}
[11]:
# In case a user needs to make more complicated changes
# to the base TARDIS model (i.e. using parameters that
# are not valid TARDIS Configuration keys), the grid
# can return a SimulationState object for a given row.
atom_data = AtomData.from_hdf(tg.config.atom_data)
simulation_state = tg.grid_row_to_simulation_state(row_index=0, atomic_data=atom_data)
simulation_state
Number of density points larger than number of shells. Assuming inner point irrelevant
[11]:
<tardis.model.base.SimulationState at 0x7fcaad72daf0>
[12]:
# Users can easily run a full TARDIS simulation
# using the grid.
sim = tg.run_sim_from_grid(row_index=0)
[tardis.io.model.parse_atom_data][INFO ]
Reading Atomic Data from kurucz_cd23_chianti_H_He.h5 (parse_atom_data.py:40)
[tardis.io.atom_data.util][INFO ]
Atom Data kurucz_cd23_chianti_H_He.h5 not found in local path.
Exists in TARDIS Data repo /home/runner/Downloads/tardis-data/kurucz_cd23_chianti_H_He.h5 (util.py:34)
[tardis.io.atom_data.base][INFO ]
Reading Atom Data with: UUID = 6f7b09e887a311e7a06b246e96350010 MD5 = 864f1753714343c41f99cb065710cace (base.py:262)
[tardis.io.atom_data.base][INFO ]
Non provided Atomic Data: synpp_refs, photoionization_data, yg_data, two_photon_data, linelist_atoms, linelist_molecules (base.py:266)
[tardis.io.model.parse_density_configuration][WARNING]
Number of density points larger than number of shells. Assuming inner point irrelevant (parse_density_configuration.py:114)
[tardis.model.matter.decay][INFO ]
Decaying abundances for 864000.0 seconds (decay.py:101)
[tardis.plasma.properties.atomic][WARNING]
Zeta_data missing - replaced with 1s. Missing ions: [] (atomic.py:601)
[tardis.plasma.properties.atomic][WARNING]
Zeta_data missing - replaced with 1s. Missing ions: [] (atomic.py:601)
[tardis.simulation.base][INFO ]
Starting iteration 1 of 2 (base.py:450)
[py.warnings ][WARNING]
/home/runner/work/tardis/tardis/tardis/transport/montecarlo/montecarlo_main_loop.py:123: NumbaTypeSafetyWarning: unsafe cast from uint64 to int64. Precision may be lost.
vpacket_collection = vpacket_collections[i]
(warnings.py:112)
[tardis.simulation.base][INFO ]
Luminosity emitted = 1.992e+41 erg / s
Luminosity absorbed = 5.852e+39 erg / s
Luminosity requested = 5.679e+41 erg / s
(base.py:663)
[tardis.simulation.base][INFO ]
Plasma stratification: (base.py:631)
Shell No. | t_rad | next_t_rad | w | next_w |
---|---|---|---|---|
0 | 5e+03 K | 5.01e+03 K | 0.39 | 0.4 |
5 | 4.95e+03 K | 4.95e+03 K | 0.19 | 0.195 |
10 | 4.91e+03 K | 4.9e+03 K | 0.123 | 0.127 |
15 | 4.87e+03 K | 4.86e+03 K | 0.0869 | 0.0907 |
[tardis.simulation.base][INFO ]
Current t_inner = 5000.000 K
Expected t_inner for next iteration = 6721.214 K
(base.py:658)
[tardis.simulation.base][INFO ]
Simulation finished in 1 iterations
Simulation took 63.64 s
(base.py:548)
[tardis.simulation.base][INFO ]
Starting iteration 2 of 2 (base.py:450)
[tardis.simulation.base][INFO ]
Luminosity emitted = 7.255e+41 erg / s
Luminosity absorbed = 2.204e+40 erg / s
Luminosity requested = 5.679e+41 erg / s
(base.py:663)