Exceptions API¶
All PHOENIX exception classes.
Exception Hierarchy¶
PhoenixError (base)
├── InvalidSmilesError
├── UnsupportedElementError
├── UnsupportedStructureError
├── MissingGroupError
├── DecompositionError
└── BalanceError
├── OverconstrainedError
└── UnderconstrainedError
PhoenixError¶
PhoenixError ¶
Bases: Exception
Base exception for all PHOENIX errors.
Base exception for all PHOENIX errors.
from phoenix import PhoenixError
try:
# PHOENIX operations
pass
except PhoenixError as e:
print(f"PHOENIX error: {e}")
InvalidSmilesError¶
InvalidSmilesError ¶
Raised when a SMILES string cannot be parsed.
Attributes¶
| Attribute | Type | Description |
|---|---|---|
smiles |
str | The invalid SMILES string |
Example¶
from phoenix import Compound, InvalidSmilesError
try:
compound = Compound.from_smiles("not-valid")
except InvalidSmilesError as e:
print(f"Invalid SMILES: {e.smiles}")
UnsupportedElementError¶
UnsupportedElementError ¶
Raised when a compound contains unsupported elements.
Attributes¶
| Attribute | Type | Description |
|---|---|---|
elements |
list[str] | List of unsupported element symbols |
Example¶
from phoenix import Compound, UnsupportedElementError
try:
compound = Compound.from_smiles("[Fe]")
except UnsupportedElementError as e:
print(f"Unsupported elements: {e.elements}")
Supported Elements¶
C, H, N, O, S, P, F, Cl, Br
UnsupportedStructureError¶
UnsupportedStructureError ¶
Raised for valid SMILES with unsupported molecular structures.
Attributes¶
| Attribute | Type | Description |
|---|---|---|
reason |
str | Why the structure is unsupported |
smiles |
str | None |
Example¶
from phoenix import Compound, UnsupportedStructureError
try:
compound = Compound.from_smiles("[NH4+]")
except UnsupportedStructureError as e:
print(f"Reason: {e.reason}")
print(f"SMILES: {e.smiles}")
Unsupported Structures¶
- Charged species (ions)
- Radical species
- Coordination complexes
MissingGroupError¶
MissingGroupError ¶
Raised when Benson GA lacks group contribution data.
Attributes¶
| Attribute | Type | Description |
|---|---|---|
groups |
list[str] | List of missing group names |
Example¶
from phoenix import MissingGroupError
try:
hf = compound.enthalpy_of_formation
except MissingGroupError as e:
print(f"Missing groups: {e.groups}")
DecompositionError¶
DecompositionError ¶
Raised when decomposition calculation fails.
Attributes¶
| Attribute | Type | Description |
|---|---|---|
reason |
str | Why decomposition failed |
formula |
str | None |
Example¶
from phoenix import DecompositionError
try:
decomp = compound.max_decomposition()
except DecompositionError as e:
print(f"Reason: {e.reason}")
print(f"Formula: {e.formula}")
BalanceError¶
BalanceError ¶
Bases: PhoenixError
Base exception for reaction balancing errors.
Base exception for reaction balancing errors.
from phoenix import BalanceError
try:
rxn.balance()
except BalanceError as e:
print(f"Balance error: {e}")
OverconstrainedError¶
OverconstrainedError ¶
Bases: BalanceError
Raised when reaction constraints are inconsistent.
This occurs when user-specified coefficients violate atom conservation, making it impossible to balance the reaction.
Attributes¶
imbalances : dict[str, float] Mapping of element to imbalance amount (positive = excess product)
Raised when reaction constraints are inconsistent.
Attributes¶
| Attribute | Type | Description |
|---|---|---|
imbalances |
dict[str, float] | Element imbalances |
Imbalance Signs¶
- Positive: excess on product side
- Negative: excess on reactant side
Example¶
from phoenix import Reaction, OverconstrainedError
try:
rxn = Reaction.from_smiles(
reactants=[("CH4", 1), ("O=O", 1)],
products=[("O=C=O", 1), ("O", 2)]
)
rxn.balance()
except OverconstrainedError as e:
print(f"Imbalances: {e.imbalances}")
for elem, imb in e.imbalances.items():
side = "products" if imb > 0 else "reactants"
print(f" {elem}: {abs(imb):.2f} excess on {side}")
UnderconstrainedError¶
UnderconstrainedError ¶
Bases: BalanceError
Raised when multiple valid balanced solutions exist.
This occurs when there are too few constraints (known coefficients) relative to the number of unknowns.
Attributes¶
degrees_of_freedom : int Number of additional coefficients needed for unique solution suggestion : str | None Hint for how to resolve the issue
Raised when multiple valid solutions exist.
Attributes¶
| Attribute | Type | Description |
|---|---|---|
degrees_of_freedom |
int | Additional constraints needed |
suggestion |
str | None |
Example¶
from phoenix import Reaction, UnderconstrainedError, Auto
try:
rxn = Reaction.from_smiles(
reactants=["C", "O=O"],
products=["O=C=O", "C=O"] # Both CO2 and CO
)
rxn.balance()
except UnderconstrainedError as e:
print(f"DOF: {e.degrees_of_freedom}")
print(f"Suggestion: {e.suggestion}")
Resolution¶
Specify additional coefficients:
rxn = Reaction.from_smiles(
reactants=[("C", 1), ("O=O", Auto)],
products=[("O=C=O", 1), ("C=O", 0)] # Force no CO
)
rxn.balance()
Import All Exceptions¶
from phoenix import (
PhoenixError,
InvalidSmilesError,
UnsupportedElementError,
UnsupportedStructureError,
MissingGroupError,
DecompositionError,
BalanceError,
OverconstrainedError,
UnderconstrainedError,
)
Best Practices¶
Catch Specific First¶
try:
compound = Compound.from_smiles(smiles)
except InvalidSmilesError:
# Handle invalid SMILES
pass
except UnsupportedElementError:
# Handle unsupported elements
pass
except PhoenixError:
# Catch-all for other PHOENIX errors
pass