Working with Species
Overview
Species represent individual chemical entities (atoms, molecules, ions) in a chemical reaction network.
from jaff import Network
net = Network("networks/react_COthin")
# Access species
for species in net.species:
print(f"{species.name}: mass={species.mass:.2f} amu, charge={species.charge}")
Species Attributes
Each species object has the following attributes:
| Attribute | Type | Description |
|---|---|---|
name |
str | Species identifier (e.g., "H2", "CO", "H+") |
mass |
float | Molecular mass in atomic mass units (amu) |
charge |
int | Electric charge (0 for neutral, ±1, ±2 for ions) |
index |
int | Position in the species array |
fidx |
str | Formatted index name for code generation |
latex |
str | Formatted latex representation of the specie |
Accessing Species
By Index
# Get first species
species = net.species[0]
print(f"First species: {species.name}")
# Iterate over all species
for i, species in enumerate(net.species):
print(f"{i}: {species.name}")
By Name
# Fast lookup using dictionary
if "CO" in net.species_dict:
idx = net.species_dict["CO"]
co = net.species[idx]
print(f"CO at index {idx}, mass={co.mass}")
else:
print("CO not in network")
Using Helper Methods
# Get species object by name
co = net.get_species_object("CO")
print(f"CO: {co.mass} amu, charge={co.charge}")
# Get species index by name
idx = net.get_species_index("CO")
print(f"CO is at index {idx}")
# Get number of species
nspec = net.get_number_of_species()
print(f"Network has {nspec} species")
Species Properties
Mass
Molecular mass in atomic mass units:
Charge
Electric charge state:
# Find all ions
ions = [s for s in net.species if s.charge != 0]
print(f"Found {len(ions)} ions:")
for ion in ions[:5]:
print(f" {ion.name}: charge={ion.charge:+d}")
# Find neutral species
neutral = [s for s in net.species if s.charge == 0]
print(f"Found {len(neutral)} neutral species")
Index
Array position for code generation:
for species in net.species[:3]:
print(f"{species.name} at index {species.index}")
# Use in generated code
from jaff import Codegen
cg = Codegen(network=net, lang="c++")
# Indices will be: 0, 1, 2, ... for C++
# Indices will be: 1, 2, 3, ... for Fortran
Filtering Species
By Mass Range
# Find species between 10 and 50 amu
mid_mass = [s for s in net.species if 10 <= s.mass <= 50]
print(f"Species with mass 10-50 amu: {len(mid_mass)}")
for s in mid_mass[:5]:
print(f" {s.name}: {s.mass:.2f} amu")
By Charge
# Positive ions
cations = [s for s in net.species if s.charge > 0]
# Negative ions
anions = [s for s in net.species if s.charge < 0]
# Neutral
neutral = [s for s in net.species if s.charge == 0]
print(f"Cations: {len(cations)}")
print(f"Anions: {len(anions)}")
print(f"Neutral: {len(neutral)}")
By Element
from jaff.elements import Elements
elem = Elements(net)
# Get element truth matrix
truth_matrix = elem.get_element_truth_matrix()
# Find species containing carbon
if "C" in elem.elements:
carbon_idx = elem.elements.index("C")
carbon_species = [
net.species[i] for i in range(len(net.species))
if truth_matrix[i][carbon_idx]
]
print(f"Species containing carbon: {len(carbon_species)}")
for s in carbon_species[:5]:
print(f" {s.name}")
By Name Pattern
import re
# Find all H2X species
h2_species = [s for s in net.species if s.name.startswith("H2")]
print(f"H2X species: {[s.name for s in h2_species]}")
# Find species matching pattern
pattern = re.compile(r"C.*O") # C followed by O
co_species = [s for s in net.species if pattern.match(s.name)]
print(f"C*O species: {[s.name for s in co_species]}")
Species Statistics
Mass Distribution
import numpy as np
masses = [s.mass for s in net.species]
print(f"Average mass: {np.mean(masses):.2f} amu")
print(f"Mass range: {np.min(masses):.2f} - {np.max(masses):.2f} amu")
print(f"Median mass: {np.median(masses):.2f} amu")
Charge Distribution
from collections import Counter
charges = [s.charge for s in net.species]
charge_dist = Counter(charges)
for charge, count in sorted(charge_dist.items()):
print(f"Charge {charge:+d}: {count} species")
See Also
Next: Learn about Working with Reactions.