Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 73 additions & 44 deletions example/NeSST Guide.ipynb

Large diffs are not rendered by default.

17 changes: 16 additions & 1 deletion src/NeSST/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,19 @@
# Materials
default_mat_list = ["H", "D", "T", "C12", "Be9"]
available_materials = []
mat_dict = {}


class LazyMaterialDict(dict):
"""A dict that lazily loads default material data on first access."""

def __missing__(self, label):
from NeSST.core import initialise_material_data # lazy import avoids circular dependency

# initialise_material_data populates self[label] for valid labels
initialise_material_data(label)
if label not in self:
raise KeyError(label)
return self[label]


mat_dict = LazyMaterialDict()
3 changes: 0 additions & 3 deletions src/NeSST/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,6 @@ def initialise_material_data(label):
available_materials.append(label)


for mat in default_mat_list:
initialise_material_data(mat)

##########################################
# Primary spectral shapes & reactivities #
##########################################
Expand Down
2 changes: 2 additions & 0 deletions src/NeSST/spectral_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ def __init__(self, label, json):
self.label = label

self.json = json
print(f">> NeSST: First usage of material {label}")
print(f">> NeSST: Loading cross section data for {label}, with config {json}...")
ENDF_data = retrieve_ENDF_data(self.json)

self.A = ENDF_data["A"]
Expand Down
23 changes: 23 additions & 0 deletions tests/test_core.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import NeSST as nst
import numpy as np
import pytest
from NeSST.constants import LazyMaterialDict


def test_DTprimspecmoments_mean():
Expand Down Expand Up @@ -75,3 +76,25 @@ def test_DTprimspecmoments_variance_relative_size():
assert np.isclose((100 / DTmean) * DTstddev, 1, atol=0.3)
# Check variance is standard deviation squared
assert np.isclose(DTvar, DTstddev**2)


def test_mat_dict_is_lazy():
# mat_dict should be a LazyMaterialDict (not loaded eagerly at import)
assert isinstance(nst.mat_dict, LazyMaterialDict)


def test_mat_dict_lazy_loads_on_access():
# mat_dict should lazily load material data on first access and then cache it
# Be9 is accessed last among default materials, so test with it
label = "Be9"
# Ensure the label is accessible (loads lazily if not already cached)
mat = nst.mat_dict[label]
assert label in nst.mat_dict
# Subsequent access returns the same cached object
assert mat is nst.mat_dict[label]


def test_mat_dict_raises_for_unknown_label():
# Accessing an unknown material label should raise KeyError
with pytest.raises(KeyError):
nst.mat_dict["unknown_material_xyz"]