Source code for gtsimulation.Particle.Particle

from pathlib import Path

import numpy as np
from particle import Particle as ParticleDB

alias_list = [
    ({"nu_e"}, "nu(e)"),
    ({"nu_mu"}, "nu(mu)"),
    ({"nu_tau"}, "nu(tau)"),
    ({"neutron"}, "n"),
    ({"proton", "H1"}, "p"),
    ({"deuteron", "H2"}, "D2"),
    ({"triton", "H3"}, "T3"),
    ({"alpha"}, "He4")
]
alias_set = set().union(*[element[0] for element in alias_list])
alias_map = {}
for elements, replacement in alias_list:
    for element in elements:
        alias_map[element] = replacement

nudat = np.load(Path(__file__).resolve().parent.joinpath("nndc_nudat_data.npy"))

[docs] class Particle: def __init__(self, Name=None, PDG=None): if Name is not None: self.Name = Name name_parsed = self.__parse_name(Name) p = ParticleDB.from_name(name_parsed) self.PDG = p.pdgid.real elif PDG is not None: if (abs(PDG) // 1_000_000_000 > 0) and (PDG % 10 > 0): # ignore excited states of nuclei PDG = int(PDG / 10) * 10 self.PDG = PDG p = ParticleDB.from_pdgid(PDG) if p.programmatic_name.endswith("_bar"): self.Name = "anti_" + p.programmatic_name.split("_bar")[0] elif p.programmatic_name.endswith(("_minus", "_plus", "_0")): self.Name = p.name else: self.Name = p.programmatic_name else: raise Exception("The input parameters must contain either a Name or a PDG code.") self.Z = p.charge self.M = p.mass if p.mass is not None else 0.0 if p.pdgid.is_nucleus: self.A = p.pdgid.A try: self.tau = nudat[(nudat["z"] == np.abs(p.charge)) & (nudat["n"] == p.pdgid.A - np.abs(p.charge))]["halflife"].item() * np.sqrt(2) except ValueError: self.tau = np.inf else: self.A = 0 self.tau = p.lifetime * 1e-9 if p.lifetime is not None else np.inf @staticmethod def __parse_name(name): name_parsed = name if name.startswith("anti_"): _, name_parsed = name.split("anti_") elif name.endswith("_bar"): name_parsed, _ = name.split("_bar") if "-" in name_parsed and name_parsed.split("-")[1].isdigit(): name_parsed = "".join(name_parsed.split("-")) if name_parsed in alias_set: name_parsed = alias_map.get(name_parsed) if name.startswith("anti_") or name.endswith("_bar"): name_parsed += "~" return name_parsed
[docs] class CRParticle(Particle): def __init__(self, r=np.array([1, 0, 0]), v=np.array([1, 0, 0]), T=1, E=None, **kwargs): super().__init__(**kwargs) self.coordinates = r self.velocities = v / np.linalg.norm(v) if T is not None and T > 0: self.T = T self.E = T + self.M elif E is not None and E > 0: self.E = E self.T = E - self.M else: raise Exception("Particle without or with negative energy")