Source code for endf.records

import re
from typing import TextIO, Tuple

import numpy as np

from .function import Tabulated1D, Tabulated2D
from ._records import float_endf

ENDF_FLOAT_RE = re.compile(r'([\s\-\+]?\d*\.\d+)([\+\-]) ?(\d+)')


def py_float_endf(s: str) -> float:
    """Convert string of floating point number in ENDF to float.

    The ENDF-6 format uses an 'e-less' floating point number format,
    e.g. -1.23481+10. Trying to convert using the float built-in won't work
    because of the lack of an 'e'. This function allows such strings to be
    converted while still allowing numbers that are not in exponential notation
    to be converted as well.

    Parameters
    ----------
    s : str
        Floating-point number from an ENDF file

    Returns
    -------
    float
        The number

    """
    return float(ENDF_FLOAT_RE.sub(r'\1e\2\3', s))


def int_endf(s: str) -> int:
    """Convert string of integer number in ENDF to int.

    The ENDF-6 format technically allows integers to be represented by a field
    of all blanks. This function acts like int(s) except when s is a string of
    all whitespace, in which case zero is returned.

    Parameters
    ----------
    s : str
        Integer or spaces

    Returns
    -------
    integer
        The number or 0
    """
    return 0 if s.isspace() else int(s)


[docs] def get_text_record(file_obj) -> str: """Return data from a TEXT record in an ENDF-6 file. Parameters ---------- file_obj : file-like object ENDF-6 file to read from Returns ------- str Text within the TEXT record """ return file_obj.readline()[:66]
[docs] def get_cont_record(file_obj, skip_c=False): """Return data from a CONT record in an ENDF-6 file. Parameters ---------- file_obj : file-like object ENDF-6 file to read from skip_c : bool Determine whether to skip the first two quantities (C1, C2) of the CONT record. Returns ------- tuple The six items within the CONT record """ line = file_obj.readline() if skip_c: C1 = None C2 = None else: C1 = float_endf(line[:11]) C2 = float_endf(line[11:22]) L1 = int_endf(line[22:33]) L2 = int_endf(line[33:44]) N1 = int_endf(line[44:55]) N2 = int_endf(line[55:66]) return (C1, C2, L1, L2, N1, N2)
[docs] def get_head_record(file_obj): """Return data from a HEAD record in an ENDF-6 file. Parameters ---------- file_obj : file-like object ENDF-6 file to read from Returns ------- tuple The six items within the HEAD record """ line = file_obj.readline() ZA = int(float_endf(line[:11])) AWR = float_endf(line[11:22]) L1 = int_endf(line[22:33]) L2 = int_endf(line[33:44]) N1 = int_endf(line[44:55]) N2 = int_endf(line[55:66]) return (ZA, AWR, L1, L2, N1, N2)
def get_list_record(file_obj: TextIO) -> Tuple[list, np.ndarray]: """Return data from a LIST record in an ENDF-6 file. Parameters ---------- file_obj : file-like object ENDF-6 file to read from Returns ------- list The six items within the header numpy.ndarray The values within the list """ # determine how many items are in list items = get_cont_record(file_obj) NPL = items[4] # read items b = np.empty(NPL) for i in range((NPL - 1)//6 + 1): line = file_obj.readline() n = min(6, NPL - 6*i) for j in range(n): b[6*i + j] = float_endf(line[11*j:11*(j + 1)]) return (items, b) def get_tab1_record(file_obj): """Return data from a TAB1 record in an ENDF-6 file. Parameters ---------- file_obj : file-like object ENDF-6 file to read from Returns ------- list The six items within the header openmc.data.Tabulated1D The tabulated function """ # Determine how many interpolation regions and total points there are line = file_obj.readline() C1 = float_endf(line[:11]) C2 = float_endf(line[11:22]) L1 = int_endf(line[22:33]) L2 = int_endf(line[33:44]) n_regions = int_endf(line[44:55]) n_pairs = int_endf(line[55:66]) params = [C1, C2, L1, L2] # Read the interpolation region data, namely NBT and INT breakpoints = np.zeros(n_regions, dtype=int) interpolation = np.zeros(n_regions, dtype=int) m = 0 for i in range((n_regions - 1)//3 + 1): line = file_obj.readline() to_read = min(3, n_regions - m) for j in range(to_read): breakpoints[m] = int_endf(line[0:11]) interpolation[m] = int_endf(line[11:22]) line = line[22:] m += 1 # Read tabulated pairs x(n) and y(n) x = np.zeros(n_pairs) y = np.zeros(n_pairs) m = 0 for i in range((n_pairs - 1)//3 + 1): line = file_obj.readline() to_read = min(3, n_pairs - m) for j in range(to_read): x[m] = float_endf(line[:11]) y[m] = float_endf(line[11:22]) line = line[22:] m += 1 return params, Tabulated1D(x, y, breakpoints, interpolation)
[docs] def get_tab2_record(file_obj): # Determine how many interpolation regions and total points there are params = get_cont_record(file_obj) n_regions = params[4] # Read the interpolation region data, namely NBT and INT breakpoints = np.zeros(n_regions, dtype=int) interpolation = np.zeros(n_regions, dtype=int) m = 0 for _ in range((n_regions - 1)//3 + 1): line = file_obj.readline() to_read = min(3, n_regions - m) for _ in range(to_read): breakpoints[m] = int(line[0:11]) interpolation[m] = int(line[11:22]) line = line[22:] m += 1 return params, Tabulated2D(breakpoints, interpolation)
def get_intg_record(file_obj): """ Return data from an INTG record in an ENDF-6 file. Used to store the covariance matrix in a compact format. Parameters ---------- file_obj : file-like object ENDF-6 file to read from Returns ------- numpy.ndarray The correlation matrix described in the INTG record """ # determine how many items are in list and NDIGIT items = get_cont_record(file_obj) ndigit = items[2] npar = items[3] # Number of parameters nlines = items[4] # Lines to read NROW_RULES = {2: 18, 3: 12, 4: 11, 5: 9, 6: 8} nrow = NROW_RULES[ndigit] # read lines and build correlation matrix corr = np.identity(npar) for i in range(nlines): line = file_obj.readline() ii = int_endf(line[:5]) - 1 # -1 to account for 0 indexing jj = int_endf(line[5:10]) - 1 factor = 10**ndigit for j in range(nrow): if jj+j >= ii: break element = int_endf(line[11+(ndigit+1)*j:11+(ndigit+1)*(j+1)]) if element > 0: corr[ii, jj] = (element+0.5)/factor elif element < 0: corr[ii, jj] = (element-0.5)/factor # Symmetrize the correlation matrix corr = corr + corr.T - np.diag(corr.diagonal()) return corr