Source code for snf_simulations.data

"""Data loading module for antineutrino spectra calculations.

Provides functions to load isotope data, reactor fuel composition data, and
antineutrino spectrum data from the built-in database files.
"""

from importlib.resources import as_file, files

import numpy as np


[docs] def get_reactors() -> list[str]: """Get a list of available reactors from the database. Returns: List of reactor names. """ data_files = files("snf_simulations.data") / "reactor_data" with as_file(data_files) as path: return [file.stem for file in path.iterdir() if file.suffix == ".csv"]
[docs] def load_reactor_data(reactor: str) -> dict[str, float]: """Load in reactor isotope proportions from the database. Args: reactor: Name of the reactor to load data for. Returns: Dictionary of isotope proportions in the fuel, e.g. {"Sr90": 5.356e-4, "Y90": 1.3922e-7, ...}. """ filename = files("snf_simulations.data") / "reactor_data" / f"{reactor}.csv" # Check if file exists with as_file(filename) as filepath: if not filepath.is_file(): msg = f"Reactor {reactor} data file not found." valid_reactors = ", ".join(get_reactors()) msg += f" Valid reactors are: {valid_reactors}." raise ValueError(msg) data = np.genfromtxt( filepath, delimiter=",", skip_header=1, dtype=str, ) return {str(d[0]): float(d[1]) for d in data}
[docs] def load_isotope_data( isotopes: list[str] | None = None, ) -> tuple[dict[str, int], dict[str, float]]: """Load in isotope parameters from the database. Args: isotopes: List of isotope names to load data for. If None, load data for all isotopes in the database. Returns: Tuple of two dictionaries: - molar_masses: Dictionary of molar masses (g/mol) for each isotope. - half_lives: Dictionary of half-lives (years) for each isotope. """ data_files = files("snf_simulations.data") filename = data_files / "isotopes.csv" with as_file(filename) as filepath: if not filepath.is_file(): msg = "Isotope CSV file not found." raise ValueError(msg) data = np.genfromtxt( filepath, delimiter=",", skip_header=1, dtype=str, ) if isotopes is not None: data = data[np.isin(data[:, 0], isotopes)] molar_masses = {str(d[0]): int(d[1]) for d in data} half_lives = {str(d[0]): float(d[2]) for d in data} return molar_masses, half_lives
[docs] def load_spectrum(isotope_name: str) -> np.ndarray: """Load in antineutrino spectrum data from text files. Args: isotope_name: Name of the isotope to load data for. Returns: Array containing energy, flux, and uncertainty. """ # TODO: download spectra from IAEA database, and cache locally spec_files = files("snf_simulations.data.spec_data") filename = spec_files / f"{isotope_name}_an.txt" with as_file(filename) as filepath: if not filepath.is_file(): msg = f"Spectrum data file for {isotope_name} not found." raise ValueError(msg) data = np.genfromtxt(filepath, skip_header=1) # Some isotopes have multiple decay chains, so cut off where the # main decay chain ends based on the p_energy column. data = data[data[:, 3] == 0] return data[:, [7, 10, 11]] # energy, flux, uncertainty
[docs] def load_antineutrino_data(isotopes: list[str]) -> dict[str, np.ndarray]: """Load in antineutrino spectrum data from the IAEA. Args: isotopes: List of isotope names to load data for. Returns: Dictionary of arrays containing spectrum data for each isotope. Data arrays contain energy, flux, and uncertainty. """ data = {} for isotope in isotopes: isotope_data = load_spectrum(isotope) data[isotope] = isotope_data return data