Source code for tardis.energy_input.GXPacket

from enum import IntEnum
import numpy as np
from numba import int64, float64
from numba.experimental import jitclass

from tardis.energy_input.samplers import sample_decay_time, sample_energy
from tardis.energy_input.util import (
    get_index,
    get_random_unit_vector,
    doppler_factor_3d,
    H_CGS_KEV,
)


[docs]class GXPacketStatus(IntEnum): BETA_DECAY = -1 COMPTON_SCATTER = 0 PHOTOABSORPTION = 1 PAIR_CREATION = 2 IN_PROCESS = 3 END = 4 ESCAPED = 5
gxpacket_spec = [ ("location", float64[:]), ("direction", float64[:]), ("energy_rf", float64), ("energy_cmf", float64), ("nu_rf", float64), ("nu_cmf", float64), ("status", int64), ("shell", int64), ("time_current", float64), ("tau", float64), ]
[docs]@jitclass(gxpacket_spec) class GXPacket(object): """ Indivisible gamma-ray packet """ def __init__( self, location, direction, energy_rf, energy_cmf, nu_rf, nu_cmf, status, shell, time_current, ): self.location = location self.direction = direction self.energy_rf = energy_rf self.energy_cmf = energy_cmf self.nu_rf = nu_rf self.nu_cmf = nu_cmf self.status = status self.shell = shell self.time_current = time_current # TODO: rename to tau_event self.tau = -np.log(np.random.random()) def get_location_r(self): """Calculate radius of the packet Returns: float: packet radius """ return np.sqrt( self.location[0] ** 2.0 + self.location[1] ** 2.0 + self.location[2] ** 2.0 )
[docs]class GXPacketCollection: """ Gamma-ray packet collection """ def __init__( self, location, direction, energy_rf, energy_cmf, nu_rf, nu_cmf, status, shell, time_current, ): self.location = location self.direction = direction self.energy_rf = energy_rf self.energy_cmf = energy_cmf self.nu_rf = nu_rf self.nu_cmf = nu_cmf self.status = status self.shell = shell self.time_current = time_current self.number_of_packets = len(self.energy_rf) self.tau = -np.log(np.random.random(self.number_of_packets))
# @njit(**njit_dict_no_parallel)
[docs]def initialize_packet_properties( isotope_energy, isotope_intensity, positronium_energy, positronium_intensity, positronium_fraction, packet_energy, k, tau_start, tau_end, initial_radius, times, effective_times, average_power_per_mass, uniform_packet_energies=True, ): """Initialize the properties of an individual packet Parameters ---------- isotope_energy : numpy array _description_ isotope_intensity : numpy array _description_ positronium_energy : numpy array _description_ positronium_intensity : numpy array _description_ positronium_fraction : float _description_ packet_energy : float _description_ k : int _description_ tau_start : float _description_ tau_end : float _description_ initial_radius : float _description_ times : numpy array _description_ effective_times : numpy array _description_ Returns ------- _type_ _description_ """ decay_time = np.inf # packets sampled uniformly in time if not uniform_packet_energies: z = np.random.random() decay_time = z * times[0] + (1 - z) * times[-1] else: decay_time = sample_decay_time( tau_start, end_tau=tau_end, decay_time_min=0, decay_time_max=times[-1], ) decay_time_index = get_index(decay_time, times) cmf_energy = sample_energy(isotope_energy, isotope_intensity) z = np.random.random() if z < positronium_fraction: z = np.random.random() if cmf_energy == 511 and z > 0.25: cmf_energy = sample_energy( positronium_energy, positronium_intensity ) energy_factor = 1.0 if decay_time < times[0]: energy_factor = decay_time / times[0] decay_time = times[0] # compute the new energy factor based on the ratio of the end-chain decay power # to the average decay power if not uniform_packet_energies: energy_factor = ( get_chain_decay_power_per_ejectamass( inventory, decay_time, times[0], isotope_energy * isotope_intensity / 100, positronium_energy * positronium_intensity / 100, tau_end, ) / average_power_per_mass ) scaled_r = initial_radius * effective_times[decay_time_index] initial_location = scaled_r * get_random_unit_vector() initial_direction = get_random_unit_vector() initial_energy = packet_energy * energy_factor # draw a random gamma-ray in shell packet = GXPacket( initial_location, initial_direction, 1.0, initial_energy, 0.0, 0.0, GXPacketStatus.IN_PROCESS, k, decay_time, ) packet.energy_rf = packet.energy_cmf / doppler_factor_3d( packet.direction, packet.location, packet.time_current, ) packet.nu_cmf = cmf_energy / H_CGS_KEV packet.nu_rf = packet.nu_cmf / doppler_factor_3d( packet.direction, packet.location, packet.time_current, ) return packet, decay_time_index