def mass_energy(self) -> u.Quantity: """ Return the mass energy of the particle in joules. If the particle is an isotope or nuclide, return the mass energy of the nucleus only. If the mass of the particle is not known, then raise a `~plasmapy.utils.MissingAtomicDataError`. Examples -------- >>> proton = Particle('p+') >>> proton.mass_energy <Quantity 1.50327759e-10 J> >>> protium = Particle('H-1 0+') >>> protium.mass_energy <Quantity 1.50327759e-10 J> >>> electron = Particle('electron') >>> electron.mass_energy.to('MeV') <Quantity 0.51099895 MeV> """ try: mass = self.nuclide_mass if self.isotope else self.mass energy = mass * const.c ** 2 return energy.to(u.J) except MissingAtomicDataError: raise MissingAtomicDataError( f"The mass energy of {self.particle} is not available " f"because the mass is unknown.") from None
def half_life(self) -> Union[u.Quantity, str]: """ Return the particle's half-life in seconds, or a `str` with half-life information. Particles that do not have sufficiently well-constrained half-lives will return a `str` containing the information that is available about the half-life and issue a `~plasmapy.utils.MissingAtomicDataWarning`. Examples -------- >>> neutron = Particle('n') >>> neutron.half_life <Quantity 881.5 s> """ if self.element and not self.isotope: raise InvalidIsotopeError(_category_errmsg(self.particle, 'isotope')) if isinstance(self._attributes['half-life'], str): warnings.warn( f"The half-life for {self.particle} is not known precisely; " "returning string with estimated value.", MissingAtomicDataWarning) if self._attributes['half-life'] is None: raise MissingAtomicDataError(f"The half-life of '{self.particle}' is not available.") return self._attributes['half-life']
def lepton_number(self) -> Integral: """ Return ``1`` for leptons, ``-1`` for antileptons, and ``0`` otherwise. This attribute returns the number of leptons minus the number of antileptons, excluding bound electrons in an atom or ion. If the lepton number is unavailable, then this attribute will raise a `~plasmapy.utils.MissingAtomicDataError`. Examples -------- >>> Particle('e-').lepton_number 1 >>> Particle('mu+').lepton_number -1 >>> Particle('He-4 0+').lepton_number 0 """ if self._attributes['lepton number'] is None: # coverage: ignore raise MissingAtomicDataError( f"The lepton number for {self.particle} is not available.") return self._attributes['lepton number']
def spin(self) -> Real: """ Return the spin of the particle. If the spin is unavailable, then a `~plasmapy.utils.MissingAtomicDataError` will be raised. Examples -------- >>> positron = Particle('e+') >>> positron.spin 0.5 """ if self._attributes['spin'] is None: raise MissingAtomicDataError(f"The spin of particle '{self.particle}' is unavailable.") return self._attributes['spin']
def get_particle_mass(particle) -> u.Quantity: """Return the mass of a particle. Take a representation of a particle and returns the mass in kg. If the input is a `~astropy.units.Quantity` or `~astropy.constants.Constant` with units of mass already, then this returns that mass converted to kg. """ try: if isinstance(particle, (u.Quantity, const.Constant)): return particle.to(u.kg) if not isinstance(particle, Particle): particle = Particle(particle) return particle.mass.to(u.kg) except u.UnitConversionError as exc1: raise u.UnitConversionError(f"Incorrect units in reduced_mass.") from exc1 except MissingAtomicDataError: raise MissingAtomicDataError( f"Unable to find the reduced mass because the mass of " f"{particle} is not available.") from None
def baryon_number(self) -> Integral: """ Return the number of baryons in a particle. This attribute will return the number of protons and neutrons minus the number of antiprotons and antineutrons. The baryon number is equivalent to the mass number for isotopes. If the baryon number is unavailable, then this attribute will raise a `~plasmapy.utils.MissingAtomicDataError`. Examples -------- >>> alpha = Particle('alpha') >>> alpha.baryon_number 4 """ if self._attributes['baryon number'] is None: # coverage: ignore raise MissingAtomicDataError( f"The baryon number for '{self.particle}' is not available.") return self._attributes['baryon number']
def nuclide_mass(self) -> u.Quantity: """ Return the mass of the bare nucleus of an isotope or a neutron. This attribute will raise a `~plasmapy.utils.InvalidIsotopeError` if the particle is not an isotope or neutron, or a `~plasmapy.utils.MissingAtomicDataError` if the isotope mass is not available. Examples -------- >>> deuterium = Particle('D') >>> deuterium.nuclide_mass <Quantity 3.34358372e-27 kg> """ if self.isotope == 'H-1': return const.m_p elif self.isotope == 'D': return _special_ion_masses['D 1+'] elif self.isotope == 'T': return _special_ion_masses['T 1+'] elif self.particle == 'n': return const.m_n if not self.isotope: raise InvalidIsotopeError(_category_errmsg(self, 'isotope')) base_mass = self._attributes['isotope mass'] if base_mass is None: # coverage: ignore raise MissingAtomicDataError(f"The mass of a {self.isotope} nuclide is not available.") _nuclide_mass = self._attributes['isotope mass'] - self.atomic_number * const.m_e return _nuclide_mass.to(u.kg)
def standard_atomic_weight(self) -> u.Quantity: """ Return an element's standard atomic weight in kg. If the particle is isotope or ion or not an element, this attribute will raise an `~plasmapy.utils.InvalidElementError`. If the element does not have a defined stsandard atomic weight, this attribute will raise a `~plasmapy.utils.MissingAtomicDataError`. Examples -------- >>> oxygen = Particle('O') >>> oxygen.standard_atomic_weight <Quantity 2.65669641e-26 kg> """ if self.isotope or self.is_ion or not self.element: raise InvalidElementError(_category_errmsg(self, 'element')) if self._attributes['standard atomic weight'] is None: # coverage: ignore raise MissingAtomicDataError( f"The standard atomic weight of {self} is unavailable.") return self._attributes['standard atomic weight'].to(u.kg)
def mass(self) -> u.Quantity: """ Return the mass of the particle in kilograms. If the particle is an element and not an isotope or ion, then this attribute will return the standard atomic weight, if available. If the particle is an isotope but not an ion, then this attribute will return the isotopic mass, including bound electrons. If the particle is an ion, then this attribute will return the mass of the element or isotope (as just described) minus the product of the integer charge and the electron mass. For special particles, this attribute will return the standard value for the particle's mass. If the mass is unavailable (e.g., for neutrinos or elements with no standard atomic weight), then this attribute will raise a `~plasmapy.utils.MissingAtomicDataError`. Examples -------- >>> Particle('He').mass <Quantity 6.64647688e-27 kg> >>> Particle('He+').mass <Quantity 6.64556594e-27 kg> >>> Particle('He-4 +1').mass <Quantity 6.64556803e-27 kg> >>> Particle('alpha').mass <Quantity 6.64465709e-27 kg> """ if self._attributes['mass'] is not None: return self._attributes['mass'].to(u.kg) if self.is_ion: if self.isotope: base_mass = self._attributes['isotope mass'] else: base_mass = self._attributes['standard atomic weight'] if base_mass is None: raise MissingAtomicDataError( f"The mass of ion '{self.ionic_symbol}' is not available." ) mass = base_mass - self.integer_charge * const.m_e return mass.to(u.kg) if self.element: if self.isotope: mass = self._attributes['isotope mass'] else: mass = self._attributes['standard atomic weight'] if mass is not None: return mass.to(u.kg) raise MissingAtomicDataError(f"The mass of {self} is not available.")