added chain get daughters

This commit is contained in:
Jon Shimwell 2026-03-27 15:54:07 +01:00
parent 6cd39073b3
commit cee93b82b1
2 changed files with 75 additions and 0 deletions

View file

@ -1237,6 +1237,49 @@ class Chain:
return new_chain
def get_decay_daughters(self, nuclide):
"""Return all radioactive nuclides reachable via decay.
Unlike :meth:`reduce`, this follows only decay paths (not
reactions such as neutron capture) and returns a set of nuclide
names rather than a new :class:`Chain`. Stable nuclides are not
included in the result.
Parameters
----------
nuclide : str
Name of the parent nuclide.
Returns
-------
set of str
Names of all radioactive decay daughters reachable from the
parent.
"""
daughters = set()
stack = [nuclide]
visited = set()
while stack:
name = stack.pop()
if name in visited:
continue
visited.add(name)
if name not in self.nuclide_dict:
continue
for mode in self[name].decay_modes:
target = mode.target
if target is None or target in visited:
continue
if target not in self.nuclide_dict:
continue
target_nuc = self[target]
if target_nuc.half_life is None or target_nuc.half_life <= 0:
continue
daughters.add(target)
stack.append(target)
return daughters
def _follow(self, isotopes, level):
"""Return all isotopes present up to depth level"""
found = isotopes.copy()

View file

@ -587,3 +587,35 @@ def test_reduce(gnd_simple_chain, endf_chain):
reduced_chain = endf_chain.reduce(['U235'])
assert 'H1' in reduced_chain
assert 'H2' in reduced_chain
def test_get_decay_daughters(gnd_simple_chain):
"""Test get_decay_daughters follows only decay paths."""
# I135 decays to Xe135 (radioactive), which decays to Cs135 (stable)
daughters = gnd_simple_chain.get_decay_daughters("I135")
assert daughters == {"Xe135"}
# Xe135 decays to Cs135 (stable) — no radioactive daughters
daughters = gnd_simple_chain.get_decay_daughters("Xe135")
assert daughters == set()
# Reaction product Xe136 should NOT appear (it comes from n,gamma)
daughters = gnd_simple_chain.get_decay_daughters("I135")
assert "Xe136" not in daughters
# Stable nuclide returns empty set
daughters = gnd_simple_chain.get_decay_daughters("Cs135")
assert daughters == set()
# Nuclide not in chain returns empty set
daughters = gnd_simple_chain.get_decay_daughters("Xx999")
assert daughters == set()
def test_get_decay_daughters_cyclic(simple_chain):
"""Test get_decay_daughters handles cyclic decay chains."""
daughters = simple_chain.get_decay_daughters("A")
assert daughters == {"B"}
daughters = simple_chain.get_decay_daughters("B")
assert daughters == {"A"}