import pytest
from materials_for_mc import Nuclide
def test_be9_not_fissionable():
nuc = Nuclide('Be9')
nuc.read_nuclide_from_json('tests/Be9.json')
assert hasattr(nuc, 'fissionable'), "Nuclide should have a 'fissionable' attribute"
assert nuc.fissionable is False, "Be9 should not be fissionable"
def test_fe58_not_fissionable():
nuc = Nuclide('Fe58')
nuc.read_nuclide_from_json('tests/Fe58.json')
assert hasattr(nuc, 'fissionable'), "Nuclide should have a 'fissionable' attribute"
assert nuc.fissionable is False, "Fe58 should not be fissionable"
from materials_for_mc import Nuclide
def test_read_li6_nuclide():
nuc1 = Nuclide('Li6')
nuc1.read_nuclide_from_json('tests/Li6.json')
assert nuc1.element.lower() == 'lithium'
assert nuc1.atomic_symbol == "Li"
assert nuc1.atomic_number == 3
assert nuc1.mass_number == 6
assert nuc1.neutron_number == 3
assert nuc1.available_temperatures == ['294']
assert all(isinstance(mt, int) for mt in nuc1.reaction_mts)
cs = nuc1.reactions['294'][2]['cross_section']
for entry in cs:
assert isinstance(entry, float)
assert isinstance(entry, float)
expected_li6 = [1, 2, 3, 4, 5, 24, 27, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 101, 102, 103, 105, 203, 204, 205, 206, 207, 301, 444]
assert nuc1.reaction_mts == expected_li6
def test_read_li7_nuclide():
nuc1 = Nuclide('Li7')
nuc1.read_nuclide_from_json('tests/Li7.json')
assert nuc1.element.lower() == 'lithium'
assert nuc1.atomic_symbol == "Li"
assert nuc1.atomic_number == 3
assert nuc1.mass_number == 7
assert nuc1.neutron_number == 4
assert nuc1.available_temperatures == ['294']
assert all(isinstance(mt, int) for mt in nuc1.reaction_mts)
cs = nuc1.reactions['294'][2]['cross_section']
for entry in cs:
assert isinstance(entry, float)
assert isinstance(entry, float)
expected_li7 = [1, 2, 3, 4, 5, 16, 24, 25, 27, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 101, 102, 104, 203, 204, 205, 206, 207, 301, 444]
assert nuc1.reaction_mts == expected_li7
def test_read_be9_available_and_loaded_temperatures():
nuc = Nuclide('Be9')
nuc.read_nuclide_from_json('tests/Be9.json')
assert nuc.available_temperatures == ['294', '300']
assert hasattr(nuc, 'loaded_temperatures'), "loaded_temperatures attribute missing"
assert nuc.loaded_temperatures == ['294', '300']
assert '294' in nuc.reactions
assert '300' in nuc.reactions
def test_read_be9_mt_numbers_per_temperature():
nuc = Nuclide('Be9')
nuc.read_nuclide_from_json('tests/Be9.json')
mts_294 = sorted(int(mt) for mt in nuc.reactions['294'].keys())
mts_300 = sorted(int(mt) for mt in nuc.reactions['300'].keys())
expected_294 = sorted([
1,2,3,16,27,101,102,103,104,105,107,203,204,205,207,301,444,
875,876,877,878,879,880,881,882,883,884,885,886,887,888,889,890
])
expected_300 = sorted([
1,2,3,16,27,101,102,103,104,105,107,203,204,205,207,301
])
assert mts_294 == expected_294, f"Be9 294K MT list mismatch: {mts_294}"
assert mts_300 == expected_300, f"Be9 300K MT list mismatch: {mts_300}"
assert set(mts_300).issubset(set(mts_294))
def test_read_be9_selective_single_temperature():
nuc = Nuclide('Be9')
nuc.read_nuclide_from_json('tests/Be9.json', temperatures=['300'])
assert nuc.available_temperatures == ['294', '300'], "available_temperatures should list all temps present in file"
assert nuc.loaded_temperatures == ['300'], f"loaded_temperatures should be only ['300'], got {nuc.loaded_temperatures}"
assert '300' in nuc.reactions, "300K reactions missing after selective load"
assert '294' not in nuc.reactions, "294K reactions should not be loaded when selectively requesting only 300K"
mts_300 = sorted(int(mt) for mt in nuc.reactions['300'].keys())
expected_300 = sorted([
1,2,3,16,27,101,102,103,104,105,107,203,204,205,207,301
])
assert mts_300 == expected_300, f"Selective load 300K MT list mismatch: {mts_300}"
def test_read_nuclide_from_json_keyword():
from materials_for_mc import Nuclide
nuc = Nuclide('Li6')
nuc.read_nuclide_from_json("tendl-21")
def test_read_nuclide_from_json_local_path():
from materials_for_mc import Nuclide
nuc = Nuclide('Li6')
nuc.read_nuclide_from_json("tests/Li6.json")
def test_microscopic_cross_section_with_temperature():
from materials_for_mc import Nuclide
nuc = Nuclide('Be9')
nuc.read_nuclide_from_json('tests/Be9.json')
xs, energy = nuc.microscopic_cross_section(reaction=2, temperature='294')
assert len(xs) > 0, "Cross section data should not be empty"
assert len(energy) > 0, "Energy data should not be empty"
assert len(xs) == len(energy), "Cross section and energy arrays should have same length"
xs_300, energy_300 = nuc.microscopic_cross_section(reaction=2, temperature='300')
assert len(xs_300) > 0, "Cross section data should not be empty for 300K"
assert len(energy_300) > 0, "Energy data should not be empty for 300K"
xs_mt3, energy_mt3 = nuc.microscopic_cross_section(reaction=3, temperature='294')
assert len(xs_mt3) > 0, "MT=3 cross section data should not be empty"
assert len(energy_mt3) > 0, "MT=3 energy data should not be empty"
def test_microscopic_cross_section_without_temperature():
from materials_for_mc import Nuclide
nuc = Nuclide('Be9')
nuc.read_nuclide_from_json('tests/Be9.json', temperatures=['294'])
xs, energy = nuc.microscopic_cross_section(2)
assert len(xs) > 0, "Cross section data should not be empty"
assert len(energy) > 0, "Energy data should not be empty"
assert len(xs) == len(energy), "Cross section and energy arrays should have same length"
def test_microscopic_cross_section_multiple_temperatures_error():
from materials_for_mc import Nuclide
nuc = Nuclide('Be9')
nuc.read_nuclide_from_json('tests/Be9.json')
with pytest.raises(Exception) as exc_info:
nuc.microscopic_cross_section(2)
error_msg = str(exc_info.value)
assert "Multiple temperatures loaded" in error_msg
assert "294" in error_msg and "300" in error_msg
def test_microscopic_cross_section_invalid_temperature():
from materials_for_mc import Nuclide
nuc = Nuclide('Be9')
nuc.read_nuclide_from_json('tests/Be9.json')
with pytest.raises(Exception) as exc_info:
nuc.microscopic_cross_section(reaction=2, temperature='500')
error_msg = str(exc_info.value)
assert "Temperature '500' not found" in error_msg
assert "Available temperatures:" in error_msg
assert "294" in error_msg and "300" in error_msg
def test_microscopic_cross_section_invalid_mt():
from materials_for_mc import Nuclide
nuc = Nuclide('Be9')
nuc.read_nuclide_from_json('tests/Be9.json')
with pytest.raises(Exception) as exc_info:
nuc.microscopic_cross_section(reaction=9999, temperature='294')
error_msg = str(exc_info.value)
assert "MT 9999 not found" in error_msg
assert "Available MTs:" in error_msg
def test_microscopic_cross_section_multiple_mt_numbers():
from materials_for_mc import Nuclide
nuc = Nuclide('Be9')
nuc.read_nuclide_from_json('tests/Be9.json')
test_mts = [1, 2, 3, 16, 27, 101, 102]
for mt in test_mts:
try:
xs, energy = nuc.microscopic_cross_section(reaction=mt, temperature='294')
assert len(xs) > 0, f"MT={mt} should have cross section data"
assert len(energy) > 0, f"MT={mt} should have energy data"
assert len(xs) == len(energy), f"MT={mt} data length mismatch"
assert all(e > 0 for e in energy), f"MT={mt} energy values should be positive"
assert all(x >= 0 for x in xs), f"MT={mt} cross sections should be non-negative"
except Exception:
pass
def test_microscopic_cross_section_lithium():
from materials_for_mc import Nuclide
nuc = Nuclide('Li6')
nuc.read_nuclide_from_json('tests/Li6.json')
xs, energy = nuc.microscopic_cross_section(reaction=2) assert len(xs) > 0, "Li6 elastic scattering data should not be empty"
assert len(energy) > 0, "Li6 energy data should not be empty"
xs_explicit, energy_explicit = nuc.microscopic_cross_section(reaction=2, temperature='294')
assert xs == xs_explicit, "Results should be identical with/without explicit temperature"
assert energy == energy_explicit, "Energy should be identical with/without explicit temperature"
def test_auto_loading_from_config():
from materials_for_mc import Config
config = Config()
config.set_cross_sections({'Be9': 'tests/Be9.json'})
nuc = Nuclide('Be9')
assert nuc.loaded_temperatures == [], "Should start with no loaded temperatures"
xs, energy = nuc.microscopic_cross_section(reaction=2, temperature='294')
assert len(xs) > 0, "Auto-loaded cross section data should not be empty"
assert len(energy) > 0, "Auto-loaded energy data should not be empty"
assert len(xs) == len(energy), "Cross section and energy arrays should have same length"
def test_auto_loading_additional_temperature():
from materials_for_mc import Config
config = Config()
config.set_cross_sections({'Be9': 'tests/Be9.json'})
nuc = Nuclide('Be9')
nuc.read_nuclide_from_json('tests/Be9.json', ['294'])
assert nuc.loaded_temperatures == ['294'], "Should only have 294K loaded initially"
assert '300' in nuc.available_temperatures, "Should know 300K is available"
xs, energy = nuc.microscopic_cross_section(reaction=2, temperature='300')
assert len(xs) > 0, "Auto-loaded 300K cross section data should not be empty"
assert len(energy) > 0, "Auto-loaded 300K energy data should not be empty"
def test_auto_loading_without_config_fails():
from materials_for_mc import Config
config = Config()
original_configs = config.get_cross_sections()
config.set_cross_sections({})
try:
nuc = Nuclide('TestNuclide')
try:
nuc.microscopic_cross_section(reaction=2, temperature='294')
assert False, "Auto-loading without config should fail"
except Exception as e:
error_msg = str(e)
assert ("No configuration found" in error_msg or
"Failed to download" in error_msg or
"404 Not Found" in error_msg), f"Error should indicate missing or invalid configuration: {error_msg}"
assert "TestNuclide" in error_msg or "TestNuclide" in str(e.__class__), f"Error should be related to TestNuclide: {error_msg}"
finally:
if original_configs:
config.set_cross_sections(original_configs)
def test_auto_loading_multiple_calls_consistent():
from materials_for_mc import Config
config = Config()
config.set_cross_sections({'Be9': 'tests/Be9.json'})
nuc = Nuclide('Be9')
xs1, energy1 = nuc.microscopic_cross_section(reaction=2, temperature='294')
xs2, energy2 = nuc.microscopic_cross_section(reaction=2, temperature='294')
xs3, energy3 = nuc.microscopic_cross_section(reaction=102, temperature='300')
assert xs1 == xs2, "Multiple calls with same parameters should give identical results"
assert energy1 == energy2, "Multiple calls with same parameters should give identical energy"
assert len(xs3) > 0, "Auto-loading different MT and temperature should work"
assert len(energy3) > 0, "Auto-loading different MT and temperature should provide energy"
def test_auto_loading_with_manual_loading_combined():
from materials_for_mc import Config
config = Config()
config.set_cross_sections({'Be9': 'tests/Be9.json'})
nuc = Nuclide('Be9')
nuc.read_nuclide_from_json('tests/Be9.json', ['294'])
assert '294' in nuc.loaded_temperatures, "Manual loading should work"
assert '300' in nuc.available_temperatures, "Should know other temperatures are available"
xs_manual, energy_manual = nuc.microscopic_cross_section(reaction=2, temperature='294')
assert len(xs_manual) > 0, "Should get data for manually loaded temperature"
xs_auto, energy_auto = nuc.microscopic_cross_section(reaction=2, temperature='300')
assert len(xs_auto) > 0, "Should auto-load additional temperature"
xs_specific, energy_specific = nuc.microscopic_cross_section(reaction=444, temperature='294')
assert len(xs_specific) > 0, "Should get temperature-specific MT data"
try:
nuc.microscopic_cross_section(reaction=444, temperature='300')
print("MT=444 exists at both temperatures")
except ValueError as e:
assert "MT 444 not found" in str(e), f"Should get MT not found error, got: {e}"
def test_fendl_3_2c_keyword():
import materials_for_mc
try:
from materials_for_mc import Config
config = Config()
config.set_cross_sections({'Li6': 'fendl-3.2c'})
cross_sections = config.get_cross_sections()
assert 'Li6' in cross_sections, "Li6 should be in cross sections config"
assert cross_sections['Li6'] == 'fendl-3.2c', "Should store fendl-3.2c keyword correctly"
print("fendl-3.2c keyword test passed - keyword is recognized")
except Exception as e:
pytest.fail(f"fendl-3.2c keyword should be recognized by the system: {e}")
def test_auto_loading_with_global_keyword():
from materials_for_mc import Config, Nuclide
config = Config()
config.set_cross_sections('fendl-3.2c')
assert config.get_cross_section('Li6') == 'fendl-3.2c', "Global config should apply to Li6"
nuc = Nuclide('Li6')
assert nuc.loaded_temperatures == [], "Should start with no loaded temperatures"
try:
xs, energy = nuc.microscopic_cross_section(reaction=1, temperature='294')
assert len(xs) > 0, "Auto-loaded cross section data should not be empty"
assert len(energy) > 0, "Auto-loaded energy data should not be empty"
assert len(xs) == len(energy), "Cross section and energy arrays should have same length"
print("Auto-loading with global keyword test passed!")
except Exception as e:
if "No configuration found" in str(e):
pytest.fail(f"Config lookup failed - auto-loading should work with global keywords: {e}")
else:
print(f"Note: Auto-loading test skipped due to download issue: {e}")
def test_microscopic_cross_section_by_name():
from materials_for_mc import Nuclide
nuc = Nuclide('Be9')
nuc.read_nuclide_from_json('tests/Be9.json')
xs_name, energy_name = nuc.microscopic_cross_section("(n,elastic)", temperature='294')
assert len(xs_name) > 0, "Elastic scattering cross section should not be empty"
assert len(energy_name) > 0, "Energy data should not be empty"
xs_mt, energy_mt = nuc.microscopic_cross_section(reaction=2, temperature='294')
assert xs_name == xs_mt, "Reaction name and MT number should give identical cross sections"
assert energy_name == energy_mt, "Reaction name and MT number should give identical energy grids"
test_reactions = [
("(n,gamma)", 102), ("(n,a)", 107), ("(n,total)", 1), ]
for reaction_name, mt_num in test_reactions:
try:
xs_name, energy_name = nuc.microscopic_cross_section(reaction_name, temperature='294')
xs_mt, energy_mt = nuc.microscopic_cross_section(reaction=mt_num, temperature='294')
assert len(xs_name) > 0, f"{reaction_name} should have cross section data"
assert len(energy_name) > 0, f"{reaction_name} should have energy data"
assert xs_name == xs_mt, f"{reaction_name} and MT={mt_num} should give identical results"
assert energy_name == energy_mt, f"{reaction_name} and MT={mt_num} should give identical energy"
except Exception as e:
if "not found" in str(e).lower():
print(f"Note: {reaction_name} (MT={mt_num}) not available in Be9 data")
else:
raise e
def test_microscopic_cross_section_by_name_invalid_reaction():
from materials_for_mc import Nuclide
nuc = Nuclide('Be9')
nuc.read_nuclide_from_json('tests/Be9.json')
with pytest.raises(Exception) as exc_info:
nuc.microscopic_cross_section("invalid_reaction", temperature='294')
error_msg = str(exc_info.value)
assert "not found in reaction mapping" in error_msg or "Unknown reaction" in error_msg
def test_microscopic_cross_section_by_name_fission():
from materials_for_mc import Nuclide
nuc = Nuclide('Li6')
nuc.read_nuclide_from_json('tests/Li6.json')
try:
xs_fission, energy_fission = nuc.microscopic_cross_section("fission", temperature='294')
xs_mt18, energy_mt18 = nuc.microscopic_cross_section(18, temperature='294')
assert xs_fission == xs_mt18, "fission and MT=18 should give identical results"
assert energy_fission == energy_mt18, "fission and MT=18 should give identical energy"
except Exception as e:
if "MT 18 not found" in str(e) or "not found" in str(e).lower():
print("Note: Li6 does not have fission data (expected)")
else:
raise e
def test_sample_reaction_basic():
from materials_for_mc import Nuclide
nuc = Nuclide('Li6')
nuc.read_nuclide_from_json('tests/Li6.json')
reaction = nuc.sample_reaction(energy=1.0, temperature='294', seed=42)
if reaction is not None:
assert 'mt_number' in reaction, "Reaction should have mt_number field"
assert 'cross_section' in reaction, "Reaction should have cross_section field"
assert 'threshold_idx' in reaction, "Reaction should have threshold_idx field"
assert 'interpolation' in reaction, "Reaction should have interpolation field"
assert 'energy' in reaction, "Reaction should have energy field"
assert isinstance(reaction['mt_number'], int), "MT number should be integer"
assert isinstance(reaction['cross_section'], list), "Cross section should be list"
assert isinstance(reaction['energy'], list), "Energy should be list"
assert isinstance(reaction['threshold_idx'], int), "Threshold index should be integer"
assert isinstance(reaction['interpolation'], list), "Interpolation should be list"
assert reaction['mt_number'] > 0, "MT number should be positive"
assert len(reaction['cross_section']) > 0, "Cross section should not be empty"
assert len(reaction['energy']) > 0, "Energy grid should not be empty"
assert reaction['threshold_idx'] >= 0, "Threshold index should be non-negative"
assert all(x >= 0 for x in reaction['cross_section']), "Cross sections should be non-negative"
assert all(e > 0 for e in reaction['energy']), "Energy values should be positive"
else:
print("Note: No reaction sampled (possibly zero total cross section)")
def test_sample_reaction_reproducibility():
from materials_for_mc import Nuclide
nuc = Nuclide('Li6')
nuc.read_nuclide_from_json('tests/Li6.json')
reaction1 = nuc.sample_reaction(energy=1.0, temperature='294', seed=123)
reaction2 = nuc.sample_reaction(energy=1.0, temperature='294', seed=123)
reaction3 = nuc.sample_reaction(energy=1.0, temperature='294', seed=456)
if reaction1 is not None and reaction2 is not None:
assert reaction1['mt_number'] == reaction2['mt_number'], "Same seed should give same MT number"
assert reaction1['cross_section'] == reaction2['cross_section'], "Same seed should give same cross section data"
assert reaction1['energy'] == reaction2['energy'], "Same seed should give same energy data"
if reaction3 is not None:
assert isinstance(reaction3['mt_number'], int), "Different seed should still give valid MT number"
else:
print("Note: No reaction sampled in reproducibility test")
def test_sample_reaction_different_energies():
from materials_for_mc import Nuclide
nuc = Nuclide('Li6')
nuc.read_nuclide_from_json('tests/Li6.json')
test_energies = [1e-3, 1e-2, 1e-1, 1.0, 10.0, 100.0, 1000.0]
sampled_mts = set()
for energy in test_energies:
reaction = nuc.sample_reaction(energy=energy, temperature='294', seed=42)
if reaction is not None:
sampled_mts.add(reaction['mt_number'])
assert reaction['mt_number'] > 0, f"Valid MT number at energy {energy}"
assert len(reaction['cross_section']) > 0, f"Non-empty cross section at energy {energy}"
assert len(reaction['energy']) > 0, f"Non-empty energy grid at energy {energy}"
if len(sampled_mts) == 0:
print("Warning: No reactions sampled across all test energies")
else:
print(f"Sampled {len(sampled_mts)} different reaction types across energy range")
def test_sample_reaction_be9():
from materials_for_mc import Nuclide
nuc = Nuclide('Be9')
nuc.read_nuclide_from_json('tests/Be9.json')
reaction = nuc.sample_reaction(energy=1.0, temperature='294', seed=42)
if reaction is not None:
assert 'mt_number' in reaction, "Be9 reaction should have mt_number field"
assert isinstance(reaction['mt_number'], int), "Be9 MT number should be integer"
assert reaction['mt_number'] > 0, "Be9 MT number should be positive"
assert reaction['mt_number'] in nuc.reaction_mts, f"MT {reaction['mt_number']} should be in available MTs for Be9"
print(f"Be9 sampled reaction: MT {reaction['mt_number']}")
else:
print("Note: No Be9 reaction sampled")
def test_sample_reaction_without_seed():
from materials_for_mc import Nuclide
nuc = Nuclide('Li6')
nuc.read_nuclide_from_json('tests/Li6.json')
reaction1 = nuc.sample_reaction(energy=1.0, temperature='294')
reaction2 = nuc.sample_reaction(energy=1.0, temperature='294')
if reaction1 is not None:
assert isinstance(reaction1['mt_number'], int), "No-seed reaction 1 should be valid"
if reaction2 is not None:
assert isinstance(reaction2['mt_number'], int), "No-seed reaction 2 should be valid"
print("No-seed sampling test completed")
def test_sample_reaction_multiple_temperatures():
from materials_for_mc import Nuclide
nuc = Nuclide('Be9')
nuc.read_nuclide_from_json('tests/Be9.json')
reaction_294 = nuc.sample_reaction(energy=1.0, temperature='294', seed=42)
reaction_300 = nuc.sample_reaction(energy=1.0, temperature='300', seed=42)
if reaction_294 is not None:
assert isinstance(reaction_294['mt_number'], int), "294K reaction should be valid"
if reaction_300 is not None:
assert isinstance(reaction_300['mt_number'], int), "300K reaction should be valid"
print("Multiple temperature sampling test completed")
def test_sample_reaction_invalid_temperature():
from materials_for_mc import Nuclide
nuc = Nuclide('Li6')
nuc.read_nuclide_from_json('tests/Li6.json')
reaction = nuc.sample_reaction(energy=1.0, temperature='999', seed=42)
if reaction is not None:
assert isinstance(reaction['mt_number'], int), "Fallback temperature reaction should be valid"
print("Invalid temperature handled with fallback")
else:
print("Invalid temperature resulted in no reaction sampled")
def test_sample_reaction_edge_cases():
from materials_for_mc import Nuclide
nuc = Nuclide('Li6')
nuc.read_nuclide_from_json('tests/Li6.json')
reaction_low = nuc.sample_reaction(energy=1e-5, temperature='294', seed=42)
reaction_high = nuc.sample_reaction(energy=1e7, temperature='294', seed=42)
if reaction_low is not None:
assert isinstance(reaction_low['mt_number'], int), "Very low energy should give valid reaction"
if reaction_high is not None:
assert isinstance(reaction_high['mt_number'], int), "Very high energy should give valid reaction"
print("Edge case energy test completed")
def test_sample_reaction_zero_energy():
from materials_for_mc import Nuclide
nuc = Nuclide('Li6')
nuc.read_nuclide_from_json('tests/Li6.json')
reaction = nuc.sample_reaction(energy=0.0, temperature='294', seed=42)
if reaction is not None:
assert isinstance(reaction['mt_number'], int), "Zero energy should give valid reaction if any"
print("Zero energy test completed")
def test_sample_reaction_consistency_with_available_mts():
from materials_for_mc import Nuclide
nuc = Nuclide('Li6')
nuc.read_nuclide_from_json('tests/Li6.json')
available_mts = set(nuc.reaction_mts)
sampled_mts = set()
for i in range(100):
reaction = nuc.sample_reaction(energy=1.0, temperature='294', seed=i)
if reaction is not None:
sampled_mts.add(reaction['mt_number'])
for mt in sampled_mts:
assert mt in available_mts, f"Sampled MT {mt} should be in available MTs {available_mts}"
if sampled_mts:
print(f"Sampled MTs {sorted(sampled_mts)} are all in available MTs {sorted(available_mts)}")
else:
print("No reactions sampled in consistency test")
def test_sample_reaction_return_type():
from materials_for_mc import Nuclide
nuc = Nuclide('Li6')
nuc.read_nuclide_from_json('tests/Li6.json')
reaction = nuc.sample_reaction(energy=1.0, temperature='294', seed=42)
if reaction is not None:
assert isinstance(reaction, dict), "Reaction should be a dictionary"
assert isinstance(reaction['mt_number'], int), "mt_number should be int"
assert isinstance(reaction['cross_section'], list), "cross_section should be list"
assert isinstance(reaction['energy'], list), "energy should be list"
assert isinstance(reaction['threshold_idx'], int), "threshold_idx should be int"
assert isinstance(reaction['interpolation'], list), "interpolation should be list"
if reaction['cross_section']:
assert isinstance(reaction['cross_section'][0], float), "Cross section values should be float"
if reaction['energy']:
assert isinstance(reaction['energy'][0], float), "Energy values should be float"
if reaction['interpolation']:
assert isinstance(reaction['interpolation'][0], int), "Interpolation values should be int"
else:
assert reaction is None, "Return should be None or dict"
print("Return type test completed")
def test_nuclide_different_data_sources():
li7_tendl = Nuclide("Li7")
li7_tendl.read_nuclide_from_json("tendl-21")
li7_fendl = Nuclide("Li7")
li7_fendl.read_nuclide_from_json("fendl-3.2c")
xs_tendl, energy_tendl = li7_tendl.microscopic_cross_section("(n,gamma)")
xs_fendl, energy_fendl = li7_fendl.microscopic_cross_section("(n,gamma)")
data_different = (len(xs_tendl) != len(xs_fendl) or
any(abs(a - b) > 1e-10 for a, b in zip(xs_tendl, xs_fendl)))
assert data_different, "TENDL and FENDL data should be different"
print(f"TENDL Li7: {len(xs_tendl)} points, FENDL Li7: {len(xs_fendl)} points")
def test_nuclide_file_vs_keyword_sources():
li6_file = Nuclide("Li6")
li6_file.read_nuclide_from_json("tests/Li6.json")
li7_keyword = Nuclide("Li7")
li7_keyword.read_nuclide_from_json("tendl-21")
assert li6_file.name == "Li6"
assert li7_keyword.name == "Li7"
xs_file, _ = li6_file.microscopic_cross_section("(n,gamma)")
xs_keyword, _ = li7_keyword.microscopic_cross_section("(n,gamma)")
assert len(xs_file) > 0 and len(xs_keyword) > 0, "Both should have cross section data"
def test_nuclide_cache_respects_data_source_boundaries():
li7_tendl_1 = Nuclide("Li7")
li7_tendl_1.read_nuclide_from_json("tendl-21")
li7_fendl = Nuclide("Li7")
li7_fendl.read_nuclide_from_json("fendl-3.2c")
li7_tendl_2 = Nuclide("Li7")
li7_tendl_2.read_nuclide_from_json("tendl-21")
xs_tendl_1, _ = li7_tendl_1.microscopic_cross_section("(n,gamma)")
xs_fendl, _ = li7_fendl.microscopic_cross_section("(n,gamma)")
xs_tendl_2, _ = li7_tendl_2.microscopic_cross_section("(n,gamma)")
assert xs_tendl_1 == xs_tendl_2, "TENDL loads should be identical (cache working)"
tendl_vs_fendl_different = (len(xs_tendl_1) != len(xs_fendl) or
any(abs(a - b) > 1e-10 for a, b in zip(xs_tendl_1, xs_fendl)))
assert tendl_vs_fendl_different, "TENDL and FENDL should have different data"
def test_nuclide_path_normalization():
import os
li6_rel = Nuclide("Li6")
li6_rel.read_nuclide_from_json("tests/Li6.json")
li6_abs = Nuclide("Li6")
abs_path = os.path.abspath("tests/Li6.json")
li6_abs.read_nuclide_from_json(abs_path)
xs_rel, _ = li6_rel.microscopic_cross_section("(n,gamma)")
xs_abs, _ = li6_abs.microscopic_cross_section("(n,gamma)")
assert xs_rel == xs_abs, "Relative and absolute paths to same file should give identical results"