Пример #1
0
    def isotope_name(self) -> str:
        """
        Return the name of the element along with the isotope
        symbol if the particle corresponds to an isotope, and
        `None` otherwise.

        If the particle is not a valid element, then this
        attribute will raise an `~plasmapy.utils.InvalidElementError`.
        If it is not an isotope, then this attribute will raise an
        `~plasmapy.utils.InvalidIsotopeError`.

        Examples
        --------
        >>> deuterium = Particle("D")
        >>> deuterium.isotope_name
        'deuterium'
        >>> iron_isotope = Particle("Fe-56", Z=16)
        >>> iron_isotope.isotope_name
        'iron-56'

        """
        if not self.element:
            raise InvalidElementError(_category_errmsg(self.particle, 'element'))
        elif not self.isotope:
            raise InvalidIsotopeError(_category_errmsg(self, 'isotope'))

        if self.isotope == "D":
            isotope_name = "deuterium"
        elif self.isotope == "T":
            isotope_name = "tritium"
        else:
            isotope_name = f"{self.element_name}-{self.mass_number}"

        return isotope_name
Пример #2
0
    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']
Пример #3
0
    def isotopic_abundance(self) -> u.Quantity:
        """
        Return the isotopic abundance of an isotope.

        If the isotopic abundance is not available, this attribute will
        raise a `~plasmapy.utils.MissingAtomicDataError`.  If the
        particle is not an isotope or is an ion of an isotope, then this
        attribute will raise an `~plasmapy.utils.InvalidIsotopeError`.

        Examples
        --------
        >>> D = Particle('deuterium')
        >>> D.isotopic_abundance
        0.000115

        """
        from .atomic import common_isotopes

        if not self.isotope or self.is_ion:  # coverage: ignore
            raise InvalidIsotopeError(_category_errmsg(self.particle, 'isotope'))

        abundance = self._attributes.get('isotopic abundance', 0.0)

        if not common_isotopes(self.element):
            warnings.warn(
                f'No isotopes of {self.element} have an isotopic abundance. '
                f'The isotopic abundance of {self.isotope} is being returned as 0.0',
                AtomicWarning)

        return abundance
Пример #4
0
    def neutron_number(self) -> Integral:
        """
        Return the number of neutrons in an isotope or nucleon.

        This attribute will return the number of neutrons in an isotope,
        or ``1`` for a neutron.

        If this particle is not an isotope or neutron, then this
        attribute will raise an `~plasmapy.utils.InvalidIsotopeError`.

        Examples
        --------
        >>> alpha = Particle('He-4++')
        >>> alpha.neutron_number
        2
        >>> Particle('n').neutron_number
        1

        """
        if self.particle == 'n':
            return 1
        elif self.isotope:
            return self.mass_number - self.atomic_number
        else:  # coverage: ignore
            raise InvalidIsotopeError(_category_errmsg(self, 'isotope'))
Пример #5
0
def is_stable(particle: Particle,
              mass_numb: Optional[numbers.Integral] = None) -> bool:
    """
    Return `True` for stable isotopes and particles and `False` for
    unstable isotopes.

    Parameters
    ----------
    particle: `int`, `str`, or `~plasmapy.atomic.Particle`
        A string representing an isotope or particle, or an integer
        representing an atomic number.

    mass_numb: `int`, optional
        The mass number of the isotope.

    Returns
    -------
    is_stable: `bool`
        `True` if the isotope is stable, `False` if it is unstable.

    Raises
    ------
    `~plasmapy.utils.InvalidIsotopeError`
        If the arguments correspond to a valid element but not a
        valid isotope.

    `~plasmapy.utils.InvalidParticleError`
        If the arguments do not correspond to a valid particle.

    `TypeError`
        If the argument is not a `str` or `int`.

    `~plasmapy.utils.MissingAtomicDataError`
        If stability information is not available.

    Examples
    --------
    >>> is_stable("H-1")
    True
    >>> is_stable("tritium")
    False
    >>> is_stable("e-")
    True
    >>> is_stable("tau+")
    False

    """
    if particle.element and not particle.isotope:
        raise InvalidIsotopeError(
            "The input to is_stable must be either an isotope or a special particle."
        )
    return particle.is_category('stable')
Пример #6
0
    def binding_energy(self) -> u.Quantity:
        """
        Return the nuclear binding energy in joules.

        This attribute will raise an
        `~plasmapy.utils.InvalidIsotopeError` if the particle is not a
        nucleon or isotope.

        Examples
        --------
        >>> alpha = Particle('alpha')
        >>> alpha.binding_energy
        <Quantity 4.53346938e-12 J>
        >>> Particle('T').binding_energy.to('MeV')
        <Quantity 8.48179621 MeV>

        The binding energy of a nucleon equals 0 joules.

        >>> neutron = Particle('n')
        >>> proton = Particle('p+')
        >>> neutron.binding_energy
        <Quantity 0. J>
        >>> proton.binding_energy
        <Quantity 0. J>

        """

        if self._attributes['baryon number'] == 1:
            return 0 * u.J

        if not self.isotope:
            raise InvalidIsotopeError(
                f"The nuclear binding energy may only be calculated for nucleons and isotopes.")

        number_of_protons = self.atomic_number
        number_of_neutrons = self.mass_number - self.atomic_number

        mass_of_protons = number_of_protons * const.m_p
        mass_of_neutrons = number_of_neutrons * const.m_n

        mass_of_nucleons = mass_of_protons + mass_of_neutrons

        mass_defect = mass_of_nucleons - self.nuclide_mass
        nuclear_binding_energy = mass_defect * const.c ** 2

        return nuclear_binding_energy.to(u.J)
Пример #7
0
    def mass_number(self) -> Integral:
        """
        Return the number of nucleons in an isotope.

        This attribute will return the number of protons plus the number
        of neutrons in an isotope or nuclide.

        If the particle is not an isotope, then this attribute will
        raise an `~plasmapy.utils.InvalidIsotopeError`.

        Examples
        --------
        >>> alpha = Particle('helium-4 2+')
        >>> alpha.mass_number
        4

        """
        if not self.isotope:
            raise InvalidIsotopeError(_category_errmsg(self, 'isotope'))
        return self._attributes['mass number']
Пример #8
0
    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)