In [ ]:
import numpy as np
from tardis import constants as const
from astropy import units as u
from tardis.montecarlo.packet_source import BasePacketSource
from tardis import run_tardis
import matplotlib.pyplot as plt
from tardis.io.atom_data import download_atom_data
In [ ]:
download_atom_data('kurucz_cd23_chianti_H_He')
Custom packet source class that is derived from BasePacketSource. The method create_packets (which returns nus, mus, energies
) has to be defined.
In [ ]:
class TruncBlackbodySource(BasePacketSource):
"""
Custom inner boundary source class to replace the Blackbody source
with a truncated Blackbody source.
"""
def __init__(self, seed, truncation_wavelength):
super().__init__(seed)
self.truncation_wavelength = truncation_wavelength
def create_packets(self, T, no_of_packets,
drawing_sample_size=None):
"""
Packet source that generates a truncated Blackbody source.
Parameters
----------
T : float
Blackbody temperature
no_of_packets : int
number of packets to be created
truncation_wavelength : float
truncation wavelength in Angstrom.
Only wavelengths higher than the truncation wavelength
will be sampled.
"""
# Use mus and energies from normal blackbody source.
mus = self.create_zero_limb_darkening_packet_mus(no_of_packets)
energies = self.create_uniform_packet_energies(no_of_packets)
# If not specified, draw 2 times as many packets and reject any beyond no_of_packets.
if drawing_sample_size is None:
drawing_sample_size = 2 * no_of_packets
# Blackbody will be truncated below truncation_wavelength / above truncation_frequency.
truncation_frequency = u.Quantity(self.truncation_wavelength, u.Angstrom).to(
u.Hz, equivalencies=u.spectral()).value
# Draw nus from blackbody distribution and reject based on truncation_frequency.
# If more nus.shape[0] > no_of_packets use only the first no_of_packets.
nus = self.create_blackbody_packet_nus(T, drawing_sample_size)
nus = nus[nus<truncation_frequency][:no_of_packets]
# Only required if the truncation wavelength is too big compared to the maximum
# of the blackbody distribution. Keep sampling until nus.shape[0] > no_of_packets.
while nus.shape[0] < no_of_packets:
additional_nus = self.create_blackbody_packet_nus(
T, drawing_sample_size
)
mask = additional_nus < truncation_frequency
additional_nus = additional_nus[mask][:no_of_packets]
nus = np.hstack([nus, additional_nus])[:no_of_packets]
return nus, mus, energies
In [ ]:
packet_source = TruncBlackbodySource(
53253, truncation_wavelength=2000
)
In [ ]:
mdl = run_tardis('tardis_example.yml',
packet_source=packet_source)
mdl_norm = run_tardis('tardis_example.yml')
In [ ]:
%matplotlib inline
plt.plot(mdl.runner.spectrum_virtual.wavelength,
mdl.runner.spectrum_virtual.luminosity_density_lambda,
color='red', label='truncated blackbody')
plt.plot(mdl_norm.runner.spectrum_virtual.wavelength,
mdl_norm.runner.spectrum_virtual.luminosity_density_lambda,
color='blue', label='normal blackbody')
plt.xlabel('$\lambda [\AA]$')
plt.ylabel('$L_\lambda$ [erg/s/$\AA$]')
plt.xlim(500, 10000)
plt.legend()