CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-periodictable

Extensible periodic table of the elements with support for mass, density and X-ray/neutron scattering information

Pending
Overview
Eval results
Files

elements.mddocs/

Elements and Isotopes

Core functionality for accessing elements, isotopes, and ions from the periodic table with comprehensive property data including mass, density, atomic structure, and specialized scientific properties.

Capabilities

Element Access

Access elements from the periodic table using atomic number, symbol, or name with comprehensive property data loaded on demand.

def __getitem__(self, atomic_number: int) -> Element:
    """
    Get element by atomic number.
    
    Args:
        atomic_number: Atomic number (1-118)
        
    Returns:
        Element instance
    """

def symbol(self, symbol: str) -> Element:
    """
    Lookup element by chemical symbol.
    
    Args:
        symbol: Chemical symbol (e.g., 'Fe', 'Ni', 'H')
        
    Returns:
        Element instance
    """

def name(self, name: str) -> Element:
    """
    Lookup element by name.
    
    Args:
        name: Element name (e.g., 'iron', 'nickel', 'hydrogen')
        
    Returns:
        Element instance
    """

def isotope(self, isotope_str: str) -> Isotope:
    """
    Lookup isotope by string specification.
    
    Args:
        isotope_str: Isotope string (e.g., '56-Fe', '58-Ni')
        
    Returns:
        Isotope instance
    """

Usage examples:

import periodictable as pt

# Different ways to access iron
fe1 = pt.elements[26]        # By atomic number
fe2 = pt.elements.Fe         # By symbol attribute
fe3 = pt.elements.symbol('Fe')  # By symbol method
fe4 = pt.elements.name('iron')  # By name method

# Access specific isotopes
fe56 = pt.elements.isotope('56-Fe')  # Iron-56
ni58 = pt.elements.isotope('58-Ni')  # Nickel-58

# Special isotopes available directly
deuterium = pt.D  # Deuterium (2-H)
tritium = pt.T    # Tritium (3-H)

Element Properties

Each element provides core properties and access to isotopes and ions with lazy loading for specialized data.

class Element:
    """Individual element with properties and access to isotopes/ions."""
    
    # Core properties (always available)
    symbol: str          # Chemical symbol (e.g., 'Fe')
    name: str           # Element name (e.g., 'iron')  
    number: int         # Atomic number
    mass: float         # Atomic mass in u
    mass_units: str     # Units for mass (typically 'u')
    density: float      # Density at STP in g/cm³
    density_units: str  # Units for density
    
    # Container properties  
    isotopes: dict      # Available isotopes
    ions: dict          # Available ions
    
    def __getitem__(self, mass_number: int) -> Isotope:
        """Get isotope by mass number."""
    
    def add_isotope(self, mass_number: int) -> Isotope:
        """Add new isotope with given mass number."""
    
    @property
    def ion(self) -> dict:
        """Access ions via element.ion[charge]."""

Lazy-loaded properties (loaded when first accessed):

# Structural properties
covalent_radius: float           # Covalent radius for bonding
covalent_radius_units: str       # Units for covalent radius
covalent_radius_uncertainty: float  # Uncertainty in covalent radius
crystal_structure: str           # Crystal lattice structure

# Scattering properties
neutron: Neutron                 # Neutron scattering data
xray: Xray                      # X-ray scattering data

# Spectroscopic properties
K_alpha: float                   # K-alpha X-ray line wavelength
K_beta1: float                   # K-beta1 X-ray line wavelength
K_alpha_units: str               # Units for K-alpha
K_beta1_units: str               # Units for K-beta1

# Magnetic properties
magnetic_ff: dict                # Magnetic form factors

# Nuclear properties (isotopes only)
neutron_activation: dict         # Neutron activation data

Usage examples:

import periodictable as pt

# Basic element properties
iron = pt.Fe
print(f"Symbol: {iron.symbol}")           # Fe
print(f"Name: {iron.name}")               # iron
print(f"Atomic number: {iron.number}")    # 26
print(f"Mass: {iron.mass} {iron.mass_units}")  # Mass in atomic mass units
print(f"Density: {iron.density} {iron.density_units}")  # g/cm³

# Lazy-loaded properties (trigger data loading)
print(f"Covalent radius: {iron.covalent_radius} {iron.covalent_radius_units}")
print(f"Crystal structure: {iron.crystal_structure}")

# Check if neutron data is available
if hasattr(iron, 'neutron') and iron.neutron:
    sld = iron.neutron.sld()
    print(f"Neutron SLD: {sld}")

Isotope Access and Properties

Access specific isotopes with detailed nuclear and scattering properties beyond the natural abundance data.

class Isotope(Element):
    """Element isotope with specific mass number."""
    
    # Isotope-specific properties
    isotope: int        # Mass number
    abundance: float    # Natural abundance (if available)
    
    # Nuclear properties (when available)
    nuclear_spin: float     # Nuclear spin quantum number
    magnetic_moment: float  # Nuclear magnetic moment
    
    @property 
    def ion(self) -> dict:
        """Access ions of this isotope via isotope.ion[charge]."""

Usage examples:

import periodictable as pt

# Access isotopes
iron56 = pt.Fe[56]              # Iron-56 
nickel58 = pt.Ni[58]            # Nickel-58

# Isotope properties
print(f"Isotope: {iron56.isotope}")       # 56
print(f"Mass: {iron56.mass}")             # Isotope-specific mass

# Nuclear properties (if available)
if hasattr(iron56, 'abundance'):
    print(f"Natural abundance: {iron56.abundance}%")

# Neutron scattering for isotopes
if hasattr(iron56, 'neutron') and iron56.neutron:
    b_coh = iron56.neutron.b_c
    print(f"Coherent scattering length: {b_coh} fm")

Ion Access and Properties

Access charged states of elements and isotopes with mass corrections for electron loss/gain.

class Ion(Element):
    """Charged element or isotope."""
    
    charge: int         # Ion charge (positive for cations, negative for anions)
    
    @property
    def mass(self) -> float:
        """Mass adjusted for electron mass based on charge."""

Usage examples:

import periodictable as pt

# Access ions
fe2_ion = pt.Fe.ion[2]          # Fe²⁺ cation
fe3_ion = pt.Fe.ion[3]          # Fe³⁺ cation  
cl_ion = pt.Cl.ion[-1]         # Cl⁻ anion

# Ion properties
print(f"Charge: {fe2_ion.charge}")        # 2
print(f"Mass: {fe2_ion.mass}")            # Mass corrected for electrons

# Isotope ions
fe56_2plus = pt.Fe[56].ion[2]   # ⁵⁶Fe²⁺
print(f"Isotope: {fe56_2plus.isotope}")   # 56
print(f"Charge: {fe56_2plus.charge}")     # 2

Table Iteration and Listing

Iterate through elements and create formatted property tables for data exploration and analysis.

def __iter__(self) -> Iterator[Element]:
    """Iterate through all elements in atomic number order."""

def list(self, *props, **kwargs) -> None:
    """
    Print formatted table of element properties.
    
    Args:
        *props: Property names to display
        **kwargs: Formatting options
    """

Usage examples:

import periodictable as pt

# Iterate through all elements
for element in pt.elements:
    print(f"{element.number:3d} {element.symbol:2s} {element.name}")

# Create property tables
pt.elements.list('mass', 'density')  # Mass and density table
pt.elements.list('symbol', 'covalent_radius')  # Covalent radius table

# Filter elements (first 20)
for element in list(pt.elements)[:20]:
    if element.density:
        print(f"{element.symbol}: {element.density} g/cm³")

Type Checking Utilities

Utility functions to test the type of atomic objects for safe property access and method dispatch.

def isatom(val) -> bool:
    """Test if value is any atomic object (element, isotope, or ion)."""

def iselement(val) -> bool:
    """Test if value is an element (not isotope or ion)."""

def isisotope(val) -> bool:
    """Test if value is an isotope."""

def ision(val) -> bool:
    """Test if value is an ion."""

Usage examples:

import periodictable as pt
from periodictable.core import isatom, iselement, isisotope, ision

# Test different atomic objects
iron = pt.Fe
iron56 = pt.Fe[56]  
iron2_ion = pt.Fe.ion[2]

print(isatom(iron))      # True - all atoms
print(isatom(iron56))    # True
print(isatom(iron2_ion)) # True

print(iselement(iron))      # True - element only
print(iselement(iron56))    # False - isotope
print(iselement(iron2_ion)) # False - ion

print(isisotope(iron56))    # True - isotope
print(isisotope(iron))      # False - element

print(ision(iron2_ion))     # True - ion
print(ision(iron))          # False - element

Types

class PeriodicTable:
    """Container for all elements, isotopes, and ions."""
    def __getitem__(self, key: int) -> Element: ...
    def __iter__(self) -> Iterator[Element]: ...
    def symbol(self, symbol: str) -> Element: ...
    def name(self, name: str) -> Element: ...
    def isotope(self, isotope_str: str) -> Isotope: ...
    def list(self, *props, **kwargs) -> None: ...

class Element:
    """Individual element with properties and access to isotopes/ions."""
    symbol: str
    name: str
    number: int
    mass: float
    mass_units: str
    density: float
    density_units: str
    isotopes: dict
    ions: dict
    def __getitem__(self, mass_number: int) -> Isotope: ...
    def add_isotope(self, mass_number: int) -> Isotope: ...
    @property
    def ion(self) -> dict: ...

class Isotope(Element):
    """Element isotope with specific mass number."""
    isotope: int
    abundance: float
    nuclear_spin: float
    magnetic_moment: float

class Ion(Element):
    """Charged element or isotope."""
    charge: int
    @property
    def mass(self) -> float: ...

Install with Tessl CLI

npx tessl i tessl/pypi-periodictable

docs

constants-utilities.md

elements.md

formulas.md

index.md

neutron-scattering.md

xray-scattering.md

tile.json