Example #1
0
    def __init__(self,
                 t=0.0,
                 phi=0.0,
                 temp=300.0,
                 tol=1e-7,
                 rxs=None,
                 log=None,
                 *args,
                 **kwargs):
        """Parameters
        ----------
        t : float
            Transmutations time [sec].
        phi : float or array of floats
            Neutron flux vector [n/cm^2/sec].  Currently this must either be 
            a scalar or match the group structure of EAF.
        temp : float, optional
            Temperature [K] of material, defaults to 300.0.
        tol : float
            Tolerance level for chain truncation.
        rxs : set of ints or strs
            Reaction ids or names to use in transmutation which produce well-defined 
            children.  This set should thus not include fission.  If None, then the 
            reactions from EAF are used.
        log : file-like or None
            The log file object should be written. A None imples the log is 
            not desired.
        args : tuple, optional
            Other arguments ignored for compatibility with other Transmuters.
        kwargs : dict, optional
            Other keyword arguments ignored for compatibility with other Transmuters.
        """
        eafds = EAFDataSource()
        eafds.load(temp=temp)
        gs = np.array([eafds.src_group_struct[0], eafds.src_group_struct[-1]])
        eafds.dst_group_struct = gs
        self.xscache = XSCache(group_struct=gs,
                               data_source_classes=(NullDataSource, ))
        self.xscache.data_sources.insert(0, eafds)

        self.t = t
        self._phi = None
        self.phi = phi
        self.temp = temp
        self.log = log
        self.tol = tol
        if rxs is None:
            rxs = [
                'gamma', 'gamma_1', 'gamma_2', 'p', 'p_1', 'p_2', 'd', 'd_1',
                'd_2', 't', 't_1', 't_2', 'He3', 'He3_1', 'He3_2', 'a', 'a_1',
                'a_2', 'z_2a', 'z_2p', 'z_2p_1', 'z_2p_2', 'z_2n', 'z_2n_1',
                'z_2n_2', 'z_3n', 'z_3n_1', 'z_3n_2', 'na', 'na_1', 'na_2',
                'z_2na', 'np', 'np_1', 'np_2', 'n2a', 'nd', 'nd_1', 'nd_2',
                'nt', 'nt_1', 'nt_2', 'nHe3', 'nHe3_1', 'nHe3_2', 'z_4n',
                'z_4n_1', 'n', 'n_1', 'n_2', 'z_3np'
            ]
        rxs = set([rxname.id(rx) for rx in rxs])
        rxs.discard(rxname.id('fission'))
        self.rxs = rxs
Example #2
0
    def _load_reaction(self, nuc, rx, temp=300.0):
        """Loads reaction data from ACE files indexed by OpenMC.

        Parameters
        ----------
        nuc : int
            Nuclide id.
        rx : int
            Reaction id.
        temp : float, optional
            The nuclide temperature in [K].

        """
        rx = rxname.id(rx)
        try:
            mt = rxname.mt(rx)
        except RuntimeError:
            return None
        totrx = rxname.id('total')
        absrx = rxname.id('absorption')
        ace_tables = self._rank_ace_tables(nuc, temp=temp)
        lib = ntab = None
        for atab in ace_tables: 
            if atab not in self.libs:
                lib = self.libs[atab] = ace.Library(atab.abspath or atab.path)
                lib.read(atab.name)
            lib = self.libs[atab]
            ntab = lib.tables[atab.name]
            if mt in ntab.reactions or rx == totrx or rx == absrx:
                break
            lib = ntab = None
        if lib is None:
            return None  # no reaction available
        E_g = self.src_group_struct
        E_points = ntab.energy
        if rx == totrx:
            rawdata = ntab.sigma_t
        elif rx == absrx:
            rawdata = ntab.sigma_a
        else:
            ntabrx = ntab.reactions[mt] 
            if ntabrx.IE is None or ntabrx.IE == 0:
                rawdata = ntabrx.sigma
            else:
                rawdata = np.empty(len(E_points), dtype='f8')
                rawdata[:ntabrx.IE] = 0.0
                rawdata[ntabrx.IE:] = ntabrx.sigma
        if (E_g[0] <= E_g[-1] and E_points[-1] <= E_points[0]) or \
           (E_g[0] >= E_g[-1] and E_points[-1] >= E_points[0]):
            E_points = E_points[::-1]
            rawdata = rawdata[::-1]
        rxdata = bins.pointwise_linear_collapse(E_g, E_points, rawdata) 
        return rxdata
Example #3
0
    def _load_reaction(self, nuc, rx, temp=300.0):
        """Loads reaction data from ACE files indexed by OpenMC.

        Parameters
        ----------
        nuc : int
            Nuclide id.
        rx : int
            Reaction id.
        temp : float, optional
            The nuclide temperature in [K].

        """
        rx = rxname.id(rx)
        try:
            mt = rxname.mt(rx)
        except RuntimeError:
            return None
        totrx = rxname.id('total')
        absrx = rxname.id('absorption')
        ace_tables = self._rank_ace_tables(nuc, temp=temp)
        lib = ntab = None
        for atab in ace_tables:
            if atab not in self.libs:
                lib = self.libs[atab] = ace.Library(atab.abspath or atab.path)
                lib.read(atab.name)
            lib = self.libs[atab]
            ntab = lib.tables[atab.name]
            if mt in ntab.reactions or rx == totrx or rx == absrx:
                break
            lib = ntab = None
        if lib is None:
            return None  # no reaction available
        E_g = self.src_group_struct
        E_points = ntab.energy
        if rx == totrx:
            rawdata = ntab.sigma_t
        elif rx == absrx:
            rawdata = ntab.sigma_a
        else:
            ntabrx = ntab.reactions[mt]
            if ntabrx.IE is None or ntabrx.IE == 0:
                rawdata = ntabrx.sigma
            else:
                rawdata = np.empty(len(E_points), dtype='f8')
                rawdata[:ntabrx.IE] = 0.0
                rawdata[ntabrx.IE:] = ntabrx.sigma
        if (E_g[0] <= E_g[-1] and E_points[-1] <= E_points[0]) or \
           (E_g[0] >= E_g[-1] and E_points[-1] >= E_points[0]):
            E_points = E_points[::-1]
            rawdata = rawdata[::-1]
        rxdata = bins.pointwise_linear_collapse(E_g, E_points, rawdata)
        return rxdata
Example #4
0
    def __init__(self, t=0.0, phi=0.0, temp=300.0, tol=1e-7, rxs=None, log=None, 
                 *args, **kwargs):
        """Parameters
        ----------
        t : float
            Transmutations time [sec].
        phi : float or array of floats
            Neutron flux vector [n/cm^2/sec].  Currently this must either be 
            a scalar or match the group structure of EAF.
        temp : float, optional
            Temperature [K] of material, defaults to 300.0.
        tol : float
            Tolerance level for chain truncation.
        rxs : set of ints or strs
            Reaction ids or names to use in transmutation which produce well-defined 
            children.  This set should thus not include fission.  If None, then the 
            reactions from EAF are used.
        log : file-like or None
            The log file object should be written. A None imples the log is 
            not desired.
        args : tuple, optional
            Other arguments ignored for compatibility with other Transmuters.
        kwargs : dict, optional
            Other keyword arguments ignored for compatibility with other Transmuters.
        """
        eafds = EAFDataSource()
        eafds.load(temp=temp)
        gs = np.array([eafds.src_group_struct[0], eafds.src_group_struct[-1]])
        eafds.dst_group_struct = gs
        self.xscache = XSCache(group_struct=gs, data_source_classes=(NullDataSource,))
        self.xscache.data_sources.insert(0, eafds)

        self.t = t
        self._phi = None
        self.phi = phi
        self.temp = temp
        self.log = log
        self.tol = tol
        if rxs is None:
            rxs = ['gamma', 'gamma_1', 'gamma_2', 'p', 'p_1', 'p_2', 'd', 'd_1', 
                   'd_2', 't', 't_1', 't_2', 'He3', 'He3_1', 'He3_2', 'a', 'a_1', 
                   'a_2', 'z_2a', 'z_2p', 'z_2p_1', 'z_2p_2', 'z_2n', 'z_2n_1', 
                   'z_2n_2', 'z_3n', 'z_3n_1', 'z_3n_2', 'na', 'na_1', 'na_2', 
                   'z_2na', 'np', 'np_1', 'np_2', 'n2a', 'nd', 'nd_1', 'nd_2', 
                   'nt', 'nt_1', 'nt_2', 'nHe3', 'nHe3_1', 'nHe3_2','z_4n', 
                   'z_4n_1', 'n', 'n_1', 'n_2', 'z_3np']
        rxs = set([rxname.id(rx) for rx in rxs])
        rxs.discard(rxname.id('fission'))
        self.rxs = rxs
Example #5
0
    def reaction(self, nuc, rx, temp=300.0):
        """Gets the cross section data for this reaction channel either directly
        from the data source or from the rxcache.

        Parameters
        ----------
        nuc : int or str
            A nuclide.
        rx : int or str
            Reaction id or name.
        temp : float, optional
            Temperature [K] of material, defaults to 300.0.

        Returns
        -------
        rxdata : ndarray
            Source cross section data, length src_ngroups.

        """
        nuc = nucname.id(nuc)
        rx = rxname.id(rx)
        rxkey = (nuc, rx, temp) if self._USES_TEMP else (nuc, rx)
        if rxkey not in self.rxcache:
            self.rxcache[rxkey] = None if self.fullyloaded \
                                       else self._load_reaction(nuc, rx, temp)
        return self.rxcache[rxkey]
Example #6
0
    def load(self, temp=300.0):
        """Loads all EAF into memory.

        Parameters
        ----------
        temp : float, optional
            The material temperature

        Notes
        -----
        EAF data does not use temperature information (temp).

        """
        rxcache = self.rxcache
        avail_rx = self._avail_rx
        absrx = rxname.id('absorption')
        with tb.openFile(nuc_data, 'r') as f:
            node = f.root.neutron.eaf_xs.eaf_xs
            for row in node:
                nuc = row['nuc_zz']
                rx = avail_rx[row['rxnum']]
                xs = row['xs']
                rxcache[nuc, rx] = xs
                abskey = (nuc, absrx)
                rxcache[abskey] = xs + rxcache.get(abskey, 0.0)
        self.fullyloaded = True
Example #7
0
    def reaction(self, nuc, rx, temp=300.0):
        """Gets the cross section data for this reaction channel either directly
        from the data source or from the rxcache.

        Parameters
        ----------
        nuc : int or str
            A nuclide.
        rx : int or str
            Reaction id or name.
        temp : float, optional
            Temperature [K] of material, defaults to 300.0.

        Returns
        -------
        rxdata : ndarray
            Source cross section data, length src_ngroups.

        """
        nuc = nucname.id(nuc)
        rx = rxname.id(rx)
        rxkey = (nuc, rx, temp) if self._USES_TEMP else (nuc, rx)
        if rxkey not in self.rxcache:
            self.rxcache[rxkey] = None if self.fullyloaded \
                                       else self._load_reaction(nuc, rx, temp)
        return self.rxcache[rxkey]
Example #8
0
    def load(self, temp=300.0):
        """Loads all EAF into memory.

        Parameters
        ----------
        temp : float, optional
            The material temperature

        Notes
        -----
        EAF data does not use temperature information (temp).

        """
        rxcache = self.rxcache
        avail_rx = self._avail_rx
        absrx = rxname.id('absorption')
        with tb.openFile(nuc_data, 'r') as f:
            node = f.root.neutron.eaf_xs.eaf_xs
            for row in node:
                nuc = row['nuc_zz']
                rx = avail_rx[row['rxnum']]
                xs = row['xs']
                rxcache[nuc, rx] = xs
                abskey = (nuc, absrx)
                rxcache[abskey] = xs + rxcache.get(abskey, 0.0)
        self.fullyloaded = True
Example #9
0
    def generate(self, state, transmute_time):
        """Runs physics codes on a specific state. First runs OpenMC for transport,
        then uses the results to run ORIGEN for a single timestep.

        Parameters
        ----------
        state : namedtuple (State)
            A namedtuple containing the state parameters.
        transmute_time : float
            The length of the time step we would like to run ORIGEN for.

        Returns
        -------
        results : dict
            Dict of physics code results. Keys are either nuclide ID's or "fuel"
            for the full fuel results.
        """
        print("generating for a state with transmute_time {}".format(transmute_time))
        if state in self.statelibs:
            return self.statelibs[state]
        rc = self.rc
        k, phi_g, xstab = self.openmc(state)
        results = {"fuel": {}}
        results.update(dict(zip(rc.track_nucs, [{} for _ in rc.track_nucs])))
        if 'flux' in rc:
            phi_tot = state.flux
        elif 'fuel_specific_power' in rc:
            raise RuntimeError('needs refactor for state')
            G = len(phi_g)
            fission_id = rxname.id("fission")
            if G == 1:
                fission_xs = {xs[0]: xs[2] * 1e-24 for xs in xstab  # xs is in barns not cm2
                              if xs[1] == fission_id}
            else:
                fission_xs = {xs[0]: np.sum(xs[2]) * 1e-24 / len(xs[2]) 
                              for xs in xstab  # xs is in barns not cm2
                              if xs[1] == fission_id}
            fuel_material = self.libs["fuel"]["material"][-1]
            fuel_material.atoms_per_molecule = sum([self.rc.fuel_chemical_form[m]
                                                    for m in self.rc.fuel_chemical_form])
            fuel_atom_frac = fuel_material.to_atom_frac()
            fuel_number_density = 6.022e23 * self.rc.fuel_density / \
                (fuel_material.molecular_mass() * fuel_material.atoms_per_molecule)
            number_densities = {nuc: fuel_atom_frac[nuc] * fuel_number_density
                                for nuc in fuel_material.comp}
            sum_N_i_sig_fi = sum([number_densities[nuc] * fission_xs.get(nuc, 0)
                                  for nuc in fuel_material.comp])
            sum_N_i_sig_fi = sum_N_i_sig_fi[sum_N_i_sig_fi != 0]
            fuel_specific_power_mwcc = self.rc.fuel_density * 1e-6 * state.fuel_specific_power
            # see http://iriaxp.iri.tudelft.nl/~leege/SCALE44/origens.PDF for formula
            # (search for "the specific power due to fission", on p. 22 of the PDF)
            phi_tot = sum(3.125e16*fuel_specific_power_mwcc/sum_N_i_sig_fi)
        results = self.run_all_the_origens(state, transmute_time, phi_tot, results)
        results['xs'] = xstab
        results['phi_g'] = {'EAF': self.eafds.src_phi_g.tolist(),
                            'OpenMC': self.omcds.src_phi_g.tolist()}
        self.statelibs[state] = results
        return results
Example #10
0
    def _load_reaction(self, nuc, rx, temp=300.0):
        fissrx = rxname.id('fission')
        absrx = rxname.id('absorption')

        # Set query condition
        if rx in self._rx_avail:
            if py3k:
                cond = "(from_nuc == {0}) & (reaction_type == {1})"
            else:
                cond = "(from_nuc == {0}) & (reaction_type == '{1}')"
            cond = cond.format(nuc, self._rx_avail[rx].encode())
        elif rx == fissrx:
            cond = 'nuc == {0}'.format(nuc)
        elif rx == absrx:
            cond = "(from_nuc == {0}) & (reaction_type != b'c')".format(nuc)
        else:
            return None

        # read & collapse data
        with tb.openFile(nuc_data, 'r') as f:
            node = f.root.neutron.cinder_xs.fission if rx == fissrx else \
                   f.root.neutron.cinder_xs.absorption
            rows = [np.array(row['xs']) for row in node.where(cond)]

        if 1 == len(rows):
            rxdata = rows[0]
        elif 1 < len(rows):
            rows = np.array(rows)
            rxdata = rows.sum(axis=0)
        else:
            rxdata = None

        # add fission data to absorption
        if rx == absrx:
            fdata = self._load_reaction(nuc, fissrx)
            if fdata is not None:
                rxdata = fdata if rxdata is None else rxdata + fdata
        return rxdata
Example #11
0
    def _load_reaction(self, nuc, rx, temp=300.0):
        fissrx = rxname.id('fission')
        absrx = rxname.id('absorption')

        # Set query condition
        if rx in self._rx_avail:
            if py3k:
                cond = "(from_nuc == {0}) & (reaction_type == {1})"
            else:
                cond = "(from_nuc == {0}) & (reaction_type == '{1}')"
            cond = cond.format(nuc, self._rx_avail[rx].encode())
        elif rx == fissrx:
            cond = 'nuc == {0}'.format(nuc)
        elif rx == absrx:
            cond = "(from_nuc == {0}) & (reaction_type != b'c')".format(nuc)
        else:
            return None

        # read & collapse data
        with tb.openFile(nuc_data, 'r') as f:
            node = f.root.neutron.cinder_xs.fission if rx == fissrx else \
                   f.root.neutron.cinder_xs.absorption
            rows = [np.array(row['xs']) for row in node.where(cond)]

        if 1 == len(rows):
            rxdata = rows[0]
        elif 1 < len(rows):
            rows = np.array(rows)
            rxdata = rows.sum(axis=0)
        else:
            rxdata = None

        # add fission data to absorption
        if rx == absrx:
            fdata = self._load_reaction(nuc, fissrx)
            if fdata is not None:
                rxdata = fdata if rxdata is None else rxdata + fdata
        return rxdata
Example #12
0
def test_id_mts():
    assert_equal(rxname.id(107), _hash("a"))
    assert_equal(rxname.id(1), _hash("total"))

    assert_equal(rxname.id(long(107)), _hash("a"))
    assert_equal(rxname.id(long(1)), _hash("total"))

    assert_equal(rxname.id("107"), _hash("a"))
    assert_equal(rxname.id("1"), _hash("total"))
Example #13
0
def test_id_ids():
    assert_equal(rxname.id(_hash("a")), _hash("a"))
    assert_equal(rxname.id(_hash("total")), _hash("total"))

    assert_equal(rxname.id(long(_hash("a"))), _hash("a"))
    assert_equal(rxname.id(long(_hash("total"))), _hash("total"))

    assert_equal(rxname.id(str(_hash("a"))), _hash("a"))
    assert_equal(rxname.id(str(_hash("total"))), _hash("total"))
Example #14
0
def test_id_mts():
    assert_equal(rxname.id(107), _hash("a"))
    assert_equal(rxname.id(1), _hash("total"))

    assert_equal(rxname.id(long(107)), _hash("a"))
    assert_equal(rxname.id(long(1)), _hash("total"))

    assert_equal(rxname.id("107"), _hash("a"))
    assert_equal(rxname.id("1"), _hash("total"))
Example #15
0
def test_id_ids():
    assert_equal(rxname.id(_hash("a")), _hash("a"))
    assert_equal(rxname.id(_hash("total")), _hash("total"))

    assert_equal(rxname.id(long(_hash("a"))), _hash("a"))
    assert_equal(rxname.id(long(_hash("total"))), _hash("total"))    

    assert_equal(rxname.id(str(_hash("a"))), _hash("a"))
    assert_equal(rxname.id(str(_hash("total"))), _hash("total"))    
Example #16
0
    def _load_reaction(self, nuc, rx, temp=300.0):
        """Loads reaction specific data for EAF.

        Parameters
        ----------
        nuc : int
            Nuclide id.
        rx : int
            Reaction id.
        temp : float, optional
            The material temperature

        Notes
        -----
        EAF data does not use temperature information (temp).

        """
        absrx = rxname.id('absorption')

        if rx in self._rx_avail:
            if py3k is True:
                cond = "(nuc_zz == {0}) & (rxnum == {1})"
            else:
                cond = "(nuc_zz == {0}) & (rxnum == '{1}')"
            cond = cond.format(nuc, self._rx_avail[rx])
        elif rx == absrx:
            cond = "(nuc_zz == {0})".format(nuc)
        else:
            return None

        # Grab data
        with tb.openFile(nuc_data, 'r') as f:
            node = f.root.neutron.eaf_xs.eaf_xs
            rows = node.readWhere(cond)
            #rows = [np.array(row['xs']) for row in node.where(cond)]

        if len(rows) == 0:
            rxdata = None
        elif 1 < len(rows):
            xss = rows['xs']
            rxnums = rows['rxnum']
            for rxnum, xs in zip(rxnums, xss):
                self.rxcache[nuc, self._avail_rx[rxnum]] = xs
            rxdata = xss.sum(axis=0)
        else:
            rxdata = rows[0]['xs']

        return rxdata
Example #17
0
    def _load_reaction(self, nuc, rx, temp=300.0):
        """Loads reaction specific data for EAF.

        Parameters
        ----------
        nuc : int
            Nuclide id.
        rx : int
            Reaction id.
        temp : float, optional
            The material temperature

        Notes
        -----
        EAF data does not use temperature information (temp).

        """
        absrx = rxname.id('absorption')

        if rx in self._rx_avail:
            if py3k is True:
                cond = "(nuc_zz == {0}) & (rxnum == {1})"
            else:
                cond = "(nuc_zz == {0}) & (rxnum == '{1}')"
            cond = cond.format(nuc, self._rx_avail[rx])
        elif rx == absrx:
            cond = "(nuc_zz == {0})".format(nuc)
        else:
            return None

        # Grab data
        with tb.openFile(nuc_data, 'r') as f:
            node = f.root.neutron.eaf_xs.eaf_xs
            rows = node.readWhere(cond)
            #rows = [np.array(row['xs']) for row in node.where(cond)]

        if len(rows) == 0:
            rxdata = None
        elif 1 < len(rows):
            xss = rows['xs']
            rxnums = rows['rxnum']
            for rxnum, xs in zip(rxnums, xss):
                self.rxcache[nuc, self._avail_rx[rxnum]] = xs
            rxdata = xss.sum(axis=0)
        else:
            rxdata = rows[0]['xs']

        return rxdata
Example #18
0
def test_id_names():
    assert_equal(rxname.id("a"), _hash("a"))
    assert_equal(rxname.id("total"), _hash("total"))
Example #19
0
###############################################

# rxnames
from textwrap import TextWrapper
from prettytable import PrettyTable, FRAME
from pyne import rxname

tw = TextWrapper(initial_indent="    ", subsequent_indent="    ", 
                 break_long_words=False)
style = {"style": "margin-left:auto;margin-right:auto;"}
rxtab = PrettyTable(['reaction', 'id', 'description'])
rxtab.align['reaction'] = 'l'
rxtab.align['id'] = 'r'
rxtab.align['description'] = 'l'
for name in sorted(rxname.names):
    rxtab.add_row(["'" + name + "'", rxname.id(name), rxname.doc(name)])
rxtab = "\n".join(tw.wrap(rxtab.get_html_string(attributes=style)))

aliastab = PrettyTable(['alias', 'reaction'])
aliastab.align['alias'] = 'l'
aliastab.align['reaction'] = 'l'
for alias, rxid in sorted(rxname.altnames.items()):
    aliastab.add_row(["'" + alias + "'", "'" + rxname.name(rxid) + "'"])
aliastab = "\n".join(tw.wrap(aliastab.get_html_string(attributes=style)))

_rxname_rst = """**Reactions:**

.. raw:: html

    <div>
{0}
Example #20
0
class CinderDataSource(DataSource):
    """Cinder cross section data source. The relevant cinder cross section data must
    be present in the nuc_data for this data source to exist.  This data source does
    not use material temperature information.

    Parameters
    ----------
    kwargs : optional
        Keyword arguments to be sent to base class.

    """

    # 'h' stands for helion or 'He3'
    _rx_avail = {
        rxname.id("np_1"): "np *",
        rxname.id("a_1"): "a  *",
        rxname.id("He3_1"): "h  *",
        rxname.id("z_2p_1"): "2p *",
        rxname.id("z_3n_1"): "3n *",
        rxname.id("d_1"): "d  *",
        rxname.id("npd"): "np/d",
        rxname.id("na"): "na",
        rxname.id("excited"): "*",
        rxname.id("nd"): "nd",
        rxname.id("gamma_1"): "g  *",
        rxname.id("z_3n"): "3n",
        rxname.id("np"): "np",
        rxname.id("nt"): "nt",
        rxname.id("t"): "t",
        rxname.id("nt_1"): "nt *",
        rxname.id("z_4n_1"): "4n *",
        rxname.id("na_1"): "na *",
        rxname.id("nd_1"): "nd *",
        rxname.id("t_1"): "t  *",
        rxname.id("a"): "a",
        rxname.id("z_2p"): "2p",
        rxname.id("d"): "d",
        rxname.id("gamma"): "g",
        rxname.id("He3"): "h",
        rxname.id("n"): "n",
        rxname.id("z_4n"): "4n",
        rxname.id("p"): "p",
        rxname.id("n_1"): "n  *",
        rxname.id("z_2a"): "2a",
        rxname.id("z_2n_1"): "2n *",
        rxname.id("z_2n"): "2n",
        rxname.id("nHe3_1"): "nh *",
        rxname.id("p_1"): "p  *",
        # not real or unique absorption reactions
        # rxname.id(''): "",
        # rxname.id(''): 'x',
        # rxname.id(''): 'x  *',
        # rxname.id(''): 'c',
        # rxname.id('fission'): 'f',
    }

    _USES_TEMP = False

    def __init__(self, **kwargs):
        super(CinderDataSource, self).__init__(**kwargs)

    def _load_group_structure(self):
        """Loads the cinder energy bounds array, E_g, from nuc_data."""
        with tb.open_file(nuc_data, "r") as f:
            E_g = np.array(f.root.neutron.cinder_xs.E_g)
        self.src_group_struct = E_g

    @property
    def exists(self):
        if self._exists is None:
            with tb.open_file(nuc_data, "r") as f:
                self._exists = "/neutron/cinder_xs" in f
        return self._exists

    def _load_reaction(self, nuc, rx, temp=300.0):
        fissrx = rxname.id("fission")
        absrx = rxname.id("absorption")

        # Set query condition
        if rx in self._rx_avail:
            if py3k:
                cond = "(from_nuc == {0}) & (reaction_type == {1})"
            else:
                cond = "(from_nuc == {0}) & (reaction_type == '{1}')"
            cond = cond.format(nuc, self._rx_avail[rx].encode())
        elif rx == fissrx:
            cond = "nuc == {0}".format(nuc)
        elif rx == absrx:
            cond = "(from_nuc == {0}) & (reaction_type != b'c')".format(nuc)
        else:
            return None

        # read & collapse data
        with tb.open_file(nuc_data, "r") as f:
            node = (f.root.neutron.cinder_xs.fission
                    if rx == fissrx else f.root.neutron.cinder_xs.absorption)
            rows = [np.array(row["xs"]) for row in node.where(cond)]

        if 1 == len(rows):
            rxdata = rows[0]
        elif 1 < len(rows):
            rows = np.array(rows)
            rxdata = rows.sum(axis=0)
        else:
            rxdata = None

        # add fission data to absorption
        if rx == absrx:
            fdata = self._load_reaction(nuc, fissrx)
            if fdata is not None:
                rxdata = fdata if rxdata is None else rxdata + fdata
        return rxdata
Example #21
0
def _parse_decay_dataset(lines, decay_s):
    """
    This parses a gamma ray dataset. It returns a tuple of the parsed data.

    Parameters
    ----------
    lines : list of str
        list containing lines from one dataset of an ensdf file
    decay_s : str
        string of the decay type

    Returns
    -------
    Tuple of decay parameters which is described in detail in gamma_rays docs

    """
    gammarays = []
    betas = []
    alphas = []
    ecbp = []
    ident = _ident.match(lines[0])
    daughter = ident.group(1)
    daughter_id = abs(_to_id(daughter))
    parent = ident.group(2).split()[0]
    parent = parent.split('(')[0]
    parents = parent.split(',')
    if len(parents) > 1:
        pfinal = abs(_to_id(parents[0]))
    else:
        pfinal = abs(_to_id(parents[0][:5]))
    tfinal = None
    tfinalerr = None
    nrbr = None
    nbbr = None
    nrbr_err = None
    nbbr_err = None
    nb_err = None
    br_err = None
    nb = None
    br = None
    level = None
    special = " "
    goodgray = False
    parent2 = None
    for line in lines:
        level_l = _level_regex.match(line)
        if level_l is not None:
            level, half_lifev, from_nuc, \
            state, special = _parse_level_record(level_l)
            continue
        b_rec = _beta.match(line)
        if b_rec is not None:
            dat = _parse_beta_record(b_rec)
            if parent2 is None:
                bparent = pfinal
            else:
                bparent = parent2
            level = 0.0 if level is None else level
            bdaughter = abs(data.id_from_level(_to_id(daughter), level))
            betas.append([bparent, bdaughter, dat[0], 0.0, dat[2]])
        bc_rec = _betac.match(line)
        if bc_rec is not None:
            bcdat = _parse_beta_continuation_record(bc_rec)
            if bcdat[0] is not None:
                if bc_rec.group(2) == 'B':
                    betas[-1][3] = bcdat[0]
                else:
                    ecbp[-1][3] = bcdat[0]
                    bggc = _gc.match(line)
                    conv = _parse_gamma_continuation_record(bggc, dat[2],
                                                            dat[8])
                    if 'K' in conv:
                        ecbp[-1][-3] = conv['K'][0]
                    if 'L' in conv:
                        ecbp[-1][-2] = conv['L'][0]
                    if 'M' in conv:
                        ecbp[-1][-1] = conv['M'][0]
        a_rec = _alpha.match(line)
        if a_rec is not None:
            dat = _parse_alpha_record(a_rec)
            if parent2 is None:
                aparent = pfinal
            else:
                aparent = parent2
            level = 0.0 if level is None else level
            adaughter = abs(data.id_from_level(_to_id(daughter), level))
            alphas.append([aparent, adaughter, dat[0], dat[2]])
        ec_rec = _ec.match(line)
        if ec_rec is not None:
            dat = _parse_ec_record(ec_rec)
            if parent2 is None:
                ecparent = pfinal
            else:
                ecparent = parent2
            level = 0.0 if level is None else level
            ecdaughter = abs(data.id_from_level(_to_id(daughter), level))
            ecbp.append([ecparent, ecdaughter, dat[0], 0.0, dat[2], dat[4],
                         0, 0, 0])
            continue
        g_rec = _g.match(line)
        if g_rec is not None:
            dat = _parse_gamma_record(g_rec)
            if dat[0] is not None:
                gparent = 0
                gdaughter = 0
                if level is not None:
                    gparent = abs(data.id_from_level(_to_id(daughter), level,
                                                     special))
                    dlevel = level - dat[0]
                    gdaughter = abs(data.id_from_level(_to_id(daughter), dlevel,
                                                       special))
                if parent2 is None:
                    gp2 = pfinal
                else:
                    gp2 = parent2
                dat.insert(0, daughter_id)
                dat.insert(0, gp2)
                dat.insert(0, gdaughter)
                dat.insert(0, gparent)
                for i in range(3):
                    dat.append(0)
                gammarays.append(dat)
                goodgray = True
            else:
                goodgray = False
            continue
        gc_rec = _gc.match(line)
        if gc_rec is not None and goodgray is True:
            conv = _parse_gamma_continuation_record(gc_rec, gammarays[-1][6],
                                                    gammarays[-1][10])
            if 'K' in conv:
                gammarays[-1][-3] = conv['K'][0]
            if 'L' in conv:
                gammarays[-1][-2] = conv['L'][0]
            if 'M' in conv:
                gammarays[-1][-1] = conv['M'][0]
            continue
        n_rec = _norm.match(line)
        if n_rec is not None:
            nr, nr_err, nt, nt_err, br, br_err, nb, nb_err, nrbr, nrbr_err = \
                _parse_normalization_record(n_rec)
            if nb is not None and br is not None:
                nbbr = nb * br
            if nb_err is not None and br_err is not None and nb_err != 0:
                nbbr_err = nbbr*((br_err/br) ** 2 * (nb_err/nb) ** 2) ** 0.5
            continue
        np_rec = _normp.match(line)
        if np_rec is not None:
            nrbr2, nrbr_err2, ntbr, ntbr_err, nbbr2, nbbr_err2 = \
                _parse_production_normalization_record(np_rec)
            if nrbr2 is not None and nrbr is None:
                nrbr = nrbr2
                nrbr_err = nrbr_err2
            if nbbr2 is not None and nbbr is None:
                nbbr = nbbr2
                nbbr_err = nbbr_err2
            continue
        p_rec = _p.match(line)
        if p_rec is not None:
            # only 2 parents are supported so this can be here
            multi = False
            if parent2 is not None:
                multi = True
                pfinal = [parent2,]
                tfinal = [t,]
                tfinalerr = [terr,]
            parent2, t, terr, e, e_err, special = _parse_parent_record(p_rec)
            parent2 = abs(data.id_from_level(_to_id(parent2), e, special))
            if terr is not None and not isinstance(terr, float):
                terr = (terr[0] + terr[1])/2.0
            if multi:
                tfinal.append(t)
                tfinalerr.append(terr)
                pfinal.append(parent2)
            else:
                tfinal = t
                tfinalerr = terr
                pfinal = parent2
            continue
    if len(gammarays) > 0 or len(alphas) > 0 or len(betas) > 0 or len(ecbp) > 0:
        if len(parents) > 1 and parent2 is None:
            pfinal = []
            for item in parents:
                pfinal.append(_to_id(item))
        return pfinal, daughter_id, rxname.id(decay_s.strip().lower()), \
               tfinal, tfinalerr, \
               br, br_err, nrbr, nrbr_err, nbbr, nbbr_err, gammarays, alphas, \
               betas, ecbp
    return None
Example #22
0
def levels(filename, levellist=None):
    """
    This takes an ENSDF filename or file object and parses the ADOPTED LEVELS
    records to assign level numbers by energy. It also parses the different
    reported decay types and branching ratios.

    Parameters
    ----------
    filename : str or file
        Name of ENSDF formatted file or a file-like object containing ENSDF
        formatted data
    levellist : list of tuples
        This is a list object which all newly processed levels will be added
        to. If it's None a new one will be created.

    Returns
    -------
    levellist : list of tuples
        This is a list of all the level data. Each level has base entry with a
        reaction id of 0 and additional entries for any listed decays. The
        format of each row is:
        nuc_id : int
            The state_id of the level
        rx_id : int
            The id of the decay "reaction" in PyNE reaction id form.
        half_life : float
            Half life of the state in s
        level : float
            energy of the level in keV
        branch_ratio : float
            if rx_id != 0 this is the percent of decays in that channel
        metastable : int
            metastable id number of the level (if given)
        special : string
            single character denoting levels with unknown relation to ground
            state
    """
    badlist = ["ecsf", "34si", "|b{+-}fission", "{+24}ne",
               "{+22}ne", "24ne", "b-f", "{+20}o", "2|e", "b++ec",
               "ecp+ec2p", "ecf", "mg", "ne", "{+20}ne", "{+25}ne",
               "{+28}mg", "sf(+ec+b+)"]
    special = ""
    if levellist is None:
        levellist = []
    if isinstance(filename, str):
        with open(filename, 'r') as f:
            dat = f.read()
    else:
        dat = filename.read()
    datasets = dat.split(80 * " " + "\n")[0:-1]
    for dataset in datasets:
        lines = dataset.splitlines()
        ident = re.match(_ident, lines[0])
        if ident is None:
            continue
        if 'ADOPTED LEVELS' in ident.group(2):
            leveln = 0
            brs = {}
            level_found = False
            for line in lines:
                level_l = _level_regex.match(line)
                if level_l is not None:
                    if len(brs) > 0:
                        for key, val in brs.items():
                            goodkey = True
                            keystrip = key.replace("%", "").lower()
                            for item in badlist:
                                if keystrip == item:
                                    goodkey = False
                            if goodkey is True:
                                rx = rxname.id(keystrip)
                                branch_percent = float(val.split("(")[0])
                                levellist.append((nuc_id, rx, half_lifev,
                                                  level, branch_percent,
                                                  state, special))
                    if level_found is True:
                        levellist.append((nuc_id, 0, half_lifev, level, 0.0,
                                          state, special))
                    brs = {}
                    level, half_lifev, from_nuc, state, special = \
                        _parse_level_record(level_l)
                    if from_nuc is not None:
                        nuc_id = from_nuc + leveln
                        leveln += 1
                        level_found = True
                    else:
                        level_found = False
                    continue
                levelc = _level_cont_regex.match(line)
                if levelc is not None:
                    brs.update(_parse_level_continuation_record(levelc))
                    continue
            if len(brs) > 0:
                for key, val in brs.items():
                    goodkey = True
                    keystrip = key.replace("%", "").lower()
                    for item in badlist:
                        if keystrip == item:
                            goodkey = False
                    if goodkey is True:
                        rx = rxname.id(keystrip)
                        branch_percent = float(val.split("(")[0])
                        levellist.append((nuc_id, rx, half_lifev, level,
                                          branch_percent, state, special))
            if level_found is True:
                levellist.append((nuc_id, 0, half_lifev, level, 0.0, state,
                                  special))
    _adjust_ge100_branches(levellist)
    _adjust_metastables(levellist)
    _adjust_half_lives(levellist)
    return levellist
Example #23
0
class SimpleDataSource(DataSource):
    """Simple cross section data source based off of KAERI data.  This data source
    does not use material temperature information.

    Parameters
    ----------
    kwargs : optional
        Keyword arguments to be sent to base class.

    """
    _rx_avail = {
        rxname.id('total'): 't',
        rxname.id('scattering'): 's',
        rxname.id('elastic'): 'e',
        rxname.id('inelastic'): 'i',
        rxname.id('absorption'): 'a',
        rxname.id('gamma'): 'gamma',
        rxname.id('fission'): 'f',
        rxname.id('alpha'): 'alpha',
        rxname.id('proton'): 'proton',
        rxname.id('deut'): 'deut',
        rxname.id('trit'): 'trit',
        rxname.id('z_2n'): '2n',
        rxname.id('z_3n'): '3n',
        rxname.id('z_4n'): '4n'
    }

    def __init__(self, **kwargs):
        super(SimpleDataSource, self).__init__(**kwargs)

    @property
    def exists(self):
        if self._exists is None:
            with tb.openFile(nuc_data, 'r') as f:
                self._exists = ('/neutron/simple_xs' in f)
        return self._exists

    _USES_TEMP = False

    def _load_group_structure(self):
        """Sets the simple energy bounds array, E_g."""
        self.src_group_struct = np.array([14.0, 1.0, 2.53E-8, 0.0],
                                         dtype='float64')

    def _load_reaction(self, nuc, rx, temp=300.0):
        if rx not in self._rx_avail:
            return None
        cond = "nuc == {0}".format(nuc)
        sig = 'sigma_' + self._rx_avail[rx]
        with tb.openFile(nuc_data, 'r') as f:
            simple_xs = f.root.neutron.simple_xs
            fteen = [row[sig] for row in simple_xs.fourteen_MeV.where(cond)]
            fissn = [
                row[sig] for row in simple_xs.fission_spectrum_ave.where(cond)
            ]
            therm = [row[sig] for row in simple_xs.thermal.where(cond)]
            if 0 == len(therm):
                therm = [
                    row[sig]
                    for row in simple_xs.thermal_maxwell_ave.where(cond)
                ]
            if 0 == len(fteen) and 0 == len(fissn) and 0 == len(therm):
                rxdata = None
            else:
                rxdata = np.array([fteen[0], fissn[0], therm[0]],
                                  dtype='float64')
        return rxdata

    def discretize(self, nuc, rx, temp=300.0, src_phi_g=None, dst_phi_g=None):
        """Discretizes the reaction channel from simple group structure to that
        of the destination weighted by the group fluxes.  Since the simple data
        source consists of only thermal (2.53E-8 MeV), fission (1 MeV), and 14 MeV
        data points, the following piecewise functional form is assumed:

        .. math::

            \\sigma(E) = \\sigma(2.53E-8) \\sqrt{\\frac{2.53E-8}{E}}
            \\sigma(E) = \\frac{\sigma(14) - \\sigma(1)}{14 - 1} (E - 1) + \\sigma(1)

        Parameters
        ----------
        nuc : int or str
            A nuclide.
        rx : int or str
            Reaction key ('gamma', 'alpha', 'p', etc.) or MT number.
        temp : float, optional
            Temperature [K] of material, defaults to 300.0.
        src_phi_g : array-like, optional
            IGNORED!!!  Included for API compatability
        dst_phi_g : array-like, optional
            Group fluxes for the destiniation structure, length dst_ngroups.

        Returns
        -------
        dst_sigma : ndarray
            Destination cross section data, length dst_ngroups.

        """
        src_phi_g = self.src_phi_g if src_phi_g is None else np.asarray(
            src_phi_g)
        src_sigma = self.reaction(nuc, rx, temp)
        if src_sigma is None:
            return None
        # not the most efficient, but data sizes should be smallish
        center_g = self._dst_centers
        dst_sigma = (src_sigma[2] * np.sqrt(2.53E-8)) / np.sqrt(center_g)
        dst_fissn = ((src_sigma[0] - src_sigma[1])/13.0) * (center_g - 1.0) + \
                                                                        src_sigma[1]
        mask = (dst_sigma < dst_fissn)
        dst_sigma[mask] = dst_fissn[mask]
        if dst_phi_g is not None:
            dst_sigma = (dst_sigma * dst_phi_g) / dst_phi_g.sum()
        return dst_sigma

    @property
    def dst_group_struct(self):
        return self._dst_group_struct

    @dst_group_struct.setter
    def dst_group_struct(self, dst_group_struct):
        if dst_group_struct is None:
            self._dst_group_struct = None
            self._dst_centers = None
            self._dst_ngroups = 0
        else:
            self._dst_group_struct = np.asarray(dst_group_struct)
            self._dst_centers = (self._dst_group_struct[1:] +
                                 self._dst_group_struct[:-1]) / 2.0
            self._dst_ngroups = len(dst_group_struct) - 1
        self._src_to_dst_matrix = None
Example #24
0
def test_id_nucdelta():
    assert_equal(rxname.id("U235", "U236"), _hash("absorption"))
    assert_equal(rxname.id("U235", "Np236", "p"), _hash("absorption"))
    assert_equal(rxname.id(922350, 912350), _hash("p"))
Example #25
0
def test_id_alts():
    assert_equal(rxname.id("alpha"), _hash("a"))
    assert_equal(rxname.id("tot"), _hash("total"))
Example #26
0
    def pointwise(self, nuc, rx, temp=300.0):
        """Returns pointwise reaction data from ACE files indexed by OpenMC.

        Parameters
        ----------
        nuc : int
            Nuclide id.
        rx : int
            Reaction id.
        temp : float, optional
            The nuclide temperature in [K].

        Returns
        -------
        E_points : array-like
            The array or energy points that the reaction is evaluated at.
        rawdata : array-like
            Raw pointwise reaction data.
        """
        nuc = nucname.id(nuc)
        rx = rxname.id(rx)
        try:
            mt = rxname.mt(rx)
        except RuntimeError:
            return None
        totrx = rxname.id("total")
        absrx = rxname.id("absorption")
        ace_tables = self._rank_ace_tables(nuc, temp=temp)
        lib = ntab = None
        for atab in ace_tables:
            if os.path.isfile(atab.abspath or atab.path):
                if atab not in self.libs:
                    lib = self.libs[atab] = ace.Library(atab.abspath
                                                        or atab.path)
                    lib.read(atab.name)
                lib = self.libs[atab]
                ntab = lib.tables[atab.name]
                if mt in ntab.reactions or rx == totrx or rx == absrx:
                    break
                lib = ntab = None
        if lib is None:
            return None  # no reaction available
        E_g = self.src_group_struct
        E_points = ntab.energy
        if rx == totrx:
            rawdata = ntab.sigma_t
        elif rx == absrx:
            rawdata = ntab.sigma_a
        else:
            ntabrx = ntab.reactions[mt]
            if ntabrx.IE is None or ntabrx.IE == 0:
                rawdata = ntabrx.sigma
            else:
                rawdata = np.empty(len(E_points), dtype="f8")
                rawdata[:ntabrx.IE] = 0.0
                rawdata[ntabrx.IE:] = ntabrx.sigma
        if (E_g[0] <= E_g[-1] and E_points[-1] <= E_points[0]) or (
                E_g[0] >= E_g[-1] and E_points[-1] >= E_points[0]):
            E_points = E_points[::-1]
            rawdata = rawdata[::-1]
        return E_points, rawdata
Example #27
0
def levels(filename, levellist=None):
    """
    This takes an ENSDF filename or file object and parses the ADOPTED LEVELS
    records to assign level numbers by energy. It also parses the different
    reported decay types and branching ratios.

    Parameters
    ----------
    filename : str or file
        Name of ENSDF formatted file or a file-like object containing ENSDF
        formatted data
    levellist : list of tuples
        This is a list object which all newly processed levels will be added
        to. If it's None a new one will be created.

    Returns
    -------
    levellist : list of tuples
        This is a list of all the level data. Each level has base entry with a
        reaction id of 0 and additional entries for any listed decays. The
        format of each row is:
        nuc_id : int
            The state_id of the level
        rx_id : int
            The id of the decay "reaction" in PyNE reaction id form.
        half_life : float
            Half life of the state in s
        level : float
            energy of the level in keV
        branch_ratio : float
            if rx_id != 0 this is the percent of decays in that channel
        metastable : int
            metastable id number of the level (if given)
        special : string
            single character denoting levels with unknown relation to ground
            state
    """
    badlist = ["ecsf", "34si", "|b{+-}fission", "{+24}ne",
               "{+22}ne", "24ne", "b-f", "{+20}o", "2|e", "b++ec",
               "ecp+ec2p", "ecf", "mg", "ne", "{+20}ne", "{+25}ne",
               "{+28}mg", "sf(+ec+b+)"]
    special = ""
    if levellist is None:
        levellist = []
    if isinstance(filename, str):
        with open(filename, 'r') as f:
            dat = f.read()
    else:
        dat = filename.read()
    datasets = dat.split(80 * " " + "\n")[0:-1]
    for dataset in datasets:
        lines = dataset.splitlines()
        ident = re.match(_ident, lines[0])
        if ident is None:
            continue
        if 'ADOPTED LEVELS' in ident.group(2):
            leveln = 0
            brs = {}
            level_found = False
            for line in lines:
                level_l = _level_regex.match(line)
                if level_l is not None:
                    if len(brs) > 0:
                        for key, val in brs.items():
                            goodkey = True
                            keystrip = key.replace("%", "").lower()
                            for item in badlist:
                                if keystrip == item:
                                    goodkey = False
                            if goodkey is True:
                                rx = rxname.id(keystrip)
                                levellist.append((nuc_id, rx, half_lifev,
                                                  level, val.split("(")[0],
                                                  state, special))
                    if level_found is True:
                        levellist.append((nuc_id, 0, half_lifev, level, 0.0,
                                          state, special))
                    brs = {}
                    level, half_lifev, from_nuc, state, special = \
                        _parse_level_record(level_l)
                    if from_nuc is not None:
                        nuc_id = from_nuc + leveln
                        leveln += 1
                        level_found = True
                    else:
                        level_found = False
                    continue
                levelc = _level_cont_regex.match(line)
                if levelc is not None:
                    brs.update(_parse_level_continuation_record(levelc))
                    continue
            if len(brs) > 0:
                for key, val in brs.items():
                    goodkey = True
                    keystrip = key.replace("%", "").lower()
                    for item in badlist:
                        if keystrip == item:
                            goodkey = False
                    if goodkey is True:
                        rx = rxname.id(keystrip)
                        levellist.append((nuc_id, rx, half_lifev, level,
                                          val.split("(")[0], state, special))
            if level_found is True:
                levellist.append((nuc_id, 0, half_lifev, level, 0.0, state,
                                  special))
    return levellist
Example #28
0
def test_id_names():
    assert_equal(rxname.id("a"), _hash("a"))
    assert_equal(rxname.id("total"), _hash("total"))
Example #29
0
def _parse_decay_dataset(lines, decay_s):
    """
    This parses a gamma ray dataset. It returns a tuple of the parsed data.

    Parameters
    ----------
    lines : list of str
        list containing lines from one dataset of an ensdf file
    decay_s : str
        string of the decay type

    Returns
    -------
    Tuple of decay parameters which is described in detail in gamma_rays docs

    """
    gammarays = []
    betas = []
    alphas = []
    ecbp = []
    ident = _ident.match(lines[0])
    daughter = ident.group(1)
    daughter_id = _to_id(daughter)
    parent = ident.group(2).split()[0]
    parent = parent.split('(')[0]
    parents = parent.split(',')
    if len(parents) > 1:
        pfinal = _to_id(parents[0])
    else:
        pfinal = _to_id(parents[0][:5])
    tfinal = None
    tfinalerr = None
    nrbr = None
    nbbr = None
    nrbr_err = None
    nbbr_err = None
    nb_err = None
    br_err = None
    nb = None
    br = None
    level = None
    special = " "
    goodgray = False
    parent2 = None
    for line in lines:
        level_l = _level_regex.match(line)
        if level_l is not None:
            level, half_lifev, from_nuc, \
            state, special = _parse_level_record(level_l)
            continue
        b_rec = _beta.match(line)
        if b_rec is not None:
            dat = _parse_beta_record(b_rec)
            if parent2 is None:
                bparent = pfinal
            else:
                bparent = parent2
            level = 0.0 if level is None else level
            bdaughter = data.id_from_level(_to_id(daughter), level)
            betas.append([bparent, bdaughter, dat[0], 0.0, dat[2]])
        bc_rec = _betac.match(line)
        if bc_rec is not None:
            bcdat = _parse_beta_continuation_record(bc_rec)
            if bcdat[0] is not None:
                if bc_rec.group(2) == 'B':
                    betas[-1][3] = bcdat[0]
                else:
                    ecbp[-1][3] = bcdat[0]
                    bggc = _gc.match(line)
                    conv = _parse_gamma_continuation_record(bggc, dat[2],
                                                            dat[8])
                    if 'K' in conv:
                        ecbp[-1][-3] = conv['K'][0]
                    if 'L' in conv:
                        ecbp[-1][-2] = conv['L'][0]
                    if 'M' in conv:
                        ecbp[-1][-1] = conv['M'][0]
        a_rec = _alpha.match(line)
        if a_rec is not None:
            dat = _parse_alpha_record(a_rec)
            if parent2 is None:
                aparent = pfinal
            else:
                aparent = parent2
            level = 0.0 if level is None else level
            adaughter = data.id_from_level(_to_id(daughter), level)
            alphas.append((aparent, adaughter, dat[0], dat[2]))
        ec_rec = _ec.match(line)
        if ec_rec is not None:
            dat = _parse_ec_record(ec_rec)
            if parent2 is None:
                ecparent = pfinal
            else:
                ecparent = parent2
            level = 0.0 if level is None else level
            ecdaughter = data.id_from_level(_to_id(daughter), level)
            ecbp.append([ecparent, ecdaughter, dat[0], 0.0, dat[2], dat[4],
                         0, 0, 0])
            continue
        g_rec = _g.match(line)
        if g_rec is not None:
            dat = _parse_gamma_record(g_rec)
            if dat[0] is not None:
                gparent = 0
                gdaughter = 0
                if level is not None:
                    gparent = data.id_from_level(_to_id(daughter), level,
                                                 special)
                    dlevel = level - dat[0]
                    gdaughter = data.id_from_level(_to_id(daughter), dlevel,
                                                   special)
                if parent2 is None:
                    gp2 = pfinal
                else:
                    gp2 = parent2
                dat.insert(0, daughter_id)
                dat.insert(0, gp2)
                dat.insert(0, gdaughter)
                dat.insert(0, gparent)
                for i in range(3):
                    dat.append(0)
                gammarays.append(dat)
                goodgray = True
            else:
                goodgray = False
            continue
        gc_rec = _gc.match(line)
        if gc_rec is not None and goodgray is True:
            conv = _parse_gamma_continuation_record(gc_rec, gammarays[-1][6],
                                                    gammarays[-1][10])
            if 'K' in conv:
                gammarays[-1][-3] = conv['K'][0]
            if 'L' in conv:
                gammarays[-1][-2] = conv['L'][0]
            if 'M' in conv:
                gammarays[-1][-1] = conv['M'][0]
            continue
        n_rec = _norm.match(line)
        if n_rec is not None:
            nr, nr_err, nt, nt_err, br, br_err, nb, nb_err, nrbr, nrbr_err = \
                _parse_normalization_record(n_rec)
            if nb is not None and br is not None:
                nbbr = nb * br
            if nb_err is not None and br_err is not None and nb_err != 0:
                nbbr_err = nbbr*((br_err/br) ** 2 * (nb_err/nb) ** 2) ** 0.5
            continue
        np_rec = _normp.match(line)
        if np_rec is not None:
            nrbr2, nrbr_err2, ntbr, ntbr_err, nbbr2, nbbr_err2 = \
                _parse_production_normalization_record(np_rec)
            if nrbr2 is not None and nrbr is None:
                nrbr = nrbr2
                nrbr_err = nrbr_err2
            if nbbr2 is not None and nbbr is None:
                nbbr = nbbr2
                nbbr_err = nbbr_err2
            continue
        p_rec = _p.match(line)
        if p_rec is not None:
            # only 2 parents are supported so this can be here
            multi = False
            if parent2 is not None:
                multi = True
                pfinal = [parent2,]
                tfinal = [t,]
                tfinalerr = [terr,]
            parent2, t, terr, e, e_err, special = _parse_parent_record(p_rec)
            parent2 = data.id_from_level(_to_id(parent2), e, special)
            if terr is not None and not isinstance(terr, float):
                terr = (terr[0] + terr[1])/2.0
            if multi:
                tfinal.append(t)
                tfinalerr.append(terr)
                pfinal.append(parent2)
            else:
                tfinal = t
                tfinalerr = terr
                pfinal = parent2
            continue
    if len(gammarays) > 0 or len(alphas) > 0 or len(betas) > 0 or len(ecbp) > 0:
        if len(parents) > 1 and parent2 is None:
            pfinal = []
            for item in parents:
                pfinal.append(_to_id(item))
        return pfinal, daughter_id, rxname.id(decay_s.strip().lower()), \
               tfinal, tfinalerr, \
               br, br_err, nrbr, nrbr_err, nbbr, nbbr_err, gammarays, alphas, \
               betas, ecbp
    return None
Example #30
0
def levels(filename, levellist=None, lmap=None, lcount=0):
    badlist = ["ecsf", "34si", "|b{+-}fission", "{+24}ne",
           "{+22}ne", "24ne", "b-f", "{+20}o", "2|e", "b++ec",
           "ecp+ec2p", "ecf", "mg", "ne", "{+20}ne", "{+25}ne",
           "{+28}mg", "sf(+ec+b+)"]
    special = ""
    if levellist is None:
        levellist = []
    if lmap is None:
        lmap = dict()
    if isinstance(filename, str):
        with open(filename, 'r') as f:
            dat = f.read()
    else:
        dat = filename.read()
    datasets = dat.split(80 * " " + "\n")[0:-1]
    for dataset in datasets:
        lines = dataset.splitlines()
        ident = re.match(_ident, lines[0])
        if ident is None:
            continue
        if 'ADOPTED LEVELS' in ident.group(2):
            leveln = 0
            brs = {}
            level_found = False
            for line in lines:
                level_l = _level_regex.match(line)
                if level_l is not None:
                    if len(brs) > 0:
                        for key, val in brs.items():
                            goodkey = True
                            keystrip = key.replace("%", "").lower()
                            for item in badlist:
                                if keystrip == item:
                                    goodkey = False
                            if goodkey is True:
                                rx = rxname.id(keystrip)
                                levellist.append((nuc_id, rx, half_lifev, level, val.split("(")[0], state, special))
                    if level_found is True:
                        levellist.append((nuc_id, 0, half_lifev, level, 0.0, state, special))
                    brs = {}
                    level, half_lifev, from_nuc, state, special = \
                        _parse_level_record(level_l)
                    if from_nuc is not None:
                        nuc_id = from_nuc + leveln
                        if leveln == 0:
                            lmap.update({nuc_id: lcount})
                        leveln += 1
                        lcount += 1
                        level_found = True
                    else:
                        level_found = False
                    continue
                levelc = _level_cont_regex.match(line)
                if levelc is not None:
                    brs.update(_parse_level_continuation_record(levelc))
                    continue
            if len(brs) > 0:
                for key, val in brs.items():
                    goodkey = True
                    keystrip = key.replace("%", "").lower()
                    for item in badlist:
                        if keystrip == item:
                            goodkey = False
                    if goodkey is True:
                        rx = rxname.id(keystrip)
                        levellist.append((nuc_id, rx, half_lifev, level, val.split("(")[0], state, special))
            if level_found is True:
                levellist.append((nuc_id, 0, half_lifev, level, 0.0, state, special))
    return levellist
Example #31
0
class OpenMCDataSource(DataSource):
    """Data source for ACE data that is listed in an OpenMC cross_sections.xml
    file. This data source discretizes the reactions to a given group
    stucture when the reactions are loaded in. Reseting this source group
    structure will clear the reaction cache.
    """

    self_shield_reactions = {
        rxname.id('fission'),
        rxname.id('gamma'),
        rxname.id('total')
    }

    def __init__(self, cross_sections=None, src_group_struct=None, **kwargs):
        """Parameters
        ----------
        cross_sections : openmc.CrossSections or string or file-like, optional
            Path or file to OpenMC cross_sections.xml
        src_group_struct : array-like, optional
            The group structure to discretize the ACE data to, defaults to
            ``np.logspace(1, -9, 101)``.
        kwargs : optional
            Keyword arguments to be sent to DataSource base class.

        """
        if not isinstance(cross_sections, openmc.CrossSections):
            cross_sections = cross_sections or os.getenv('CROSS_SECTIONS')
            cross_sections = openmc.CrossSections(f=cross_sections)
        self.cross_sections = cross_sections
        self._src_group_struct = src_group_struct
        super(OpenMCDataSource, self).__init__(**kwargs)
        self.libs = {}  # cross section libraries, index by openmc.AceTables

    @property
    def exists(self):
        if self._exists is None:
            self._exists = len(self.cross_sections.ace_tables) > 0
        return self._exists

    def _load_group_structure(self):
        if self._src_group_struct is None:
            self._src_group_struct = np.logspace(1, -9, 101)
        self.src_group_struct = self._src_group_struct

    def pointwise(self, nuc, rx, temp=300.0):
        """Returns pointwise reaction data from ACE files indexed by OpenMC.

        Parameters
        ----------
        nuc : int
            Nuclide id.
        rx : int
            Reaction id.
        temp : float, optional
            The nuclide temperature in [K].

        Returns
        -------
        E_points : array-like
            The array or energy points that the reaction is evaluated at.
        rawdata : array-like
            Raw pointwise reaction data.
        """
        nuc = nucname.id(nuc)
        rx = rxname.id(rx)
        try:
            mt = rxname.mt(rx)
        except RuntimeError:
            return None
        totrx = rxname.id('total')
        absrx = rxname.id('absorption')
        ace_tables = self._rank_ace_tables(nuc, temp=temp)
        lib = ntab = None
        for atab in ace_tables:
            if os.path.isfile(atab.abspath or atab.path):
                if atab not in self.libs:
                    lib = self.libs[atab] = ace.Library(atab.abspath
                                                        or atab.path)
                    lib.read(atab.name)
                lib = self.libs[atab]
                ntab = lib.tables[atab.name]
                if mt in ntab.reactions or rx == totrx or rx == absrx:
                    break
                lib = ntab = None
        if lib is None:
            return None  # no reaction available
        E_g = self.src_group_struct
        E_points = ntab.energy
        if rx == totrx:
            rawdata = ntab.sigma_t
        elif rx == absrx:
            rawdata = ntab.sigma_a
        else:
            ntabrx = ntab.reactions[mt]
            if ntabrx.IE is None or ntabrx.IE == 0:
                rawdata = ntabrx.sigma
            else:
                rawdata = np.empty(len(E_points), dtype='f8')
                rawdata[:ntabrx.IE] = 0.0
                rawdata[ntabrx.IE:] = ntabrx.sigma
        if (E_g[0] <= E_g[-1] and E_points[-1] <= E_points[0]) or \
           (E_g[0] >= E_g[-1] and E_points[-1] >= E_points[0]):
            E_points = E_points[::-1]
            rawdata = rawdata[::-1]
        return E_points, rawdata

    def _load_reaction(self, nuc, rx, temp=300.0):
        """Loads reaction data from ACE files indexed by OpenMC.

        Parameters
        ----------
        nuc : int
            Nuclide id.
        rx : int
            Reaction id.
        temp : float, optional
            The nuclide temperature in [K].
        """
        rtn = self.pointwise(nuc, rx, temp=temp)
        if rtn is None:
            return
        E_points, rawdata = rtn
        E_g = self.src_group_struct
        if self.atom_dens.get(
                nuc, 0.0) > 1.0E19 and rx in self.self_shield_reactions:
            rxdata = self.self_shield(nuc, rx, temp, E_points, rawdata)
        else:
            rxdata = bins.pointwise_linear_collapse(E_g, E_points, rawdata)
        return rxdata

    def self_shield(self, nuc, rx, temp, E_points, xs_points):
        """Calculates the self shielded cross section for a given nuclide
        and reaction. This calculation uses the Bonderanko method.

        Parameters
        ----------
        nuc : int
            Nuclide id.
        rx : int
            Reaction id.
        temp : float, optional
            The nuclide temperature in [K].
        E_points : array like
            The point wise energies.
        xs_points : array like
            Point wise cross sections

        Returns
        -------
        rxdata : array like
            collapsed self shielded cross section for nuclide nuc and reaction
            rx
        """
        sigb = self.bkg_xs(nuc, temp=temp)
        e_n = self.src_group_struct
        sig_b = np.ones(len(E_points), 'f8')
        for n in range(len(sigb)):
            sig_b[(e_n[n] <= E_points) & (E_points <= e_n[n + 1])] = sigb[n]
        rtn = self.pointwise(nuc, 'total', temp)
        if rtn is None:
            sig_t = 0.0
        else:
            sig_t = rtn[1]
        numer = bins.pointwise_linear_collapse(
            self.src_group_struct, E_points,
            xs_points / (E_points * (sig_b + sig_t)))
        denom = bins.pointwise_linear_collapse(
            self.src_group_struct, E_points,
            1.0 / (E_points * (sig_b + sig_t)))
        return numer / denom

    def bkg_xs(self, nuc, temp=300):
        """Calculates the background cross section for a nuclide (nuc)

        Parameters
        ----------
        nuc : int
            Nuclide id.
        temp : float, optional
            The nuclide temperature in [K].

        Returns
        -------
        sig_b : array like
            Group wise background cross sections.
        """
        e_n = self.src_group_struct
        sig_b = np.zeros(self.src_ngroups, float)
        for i, a in self.atom_dens.items():
            if i == nuc:
                continue
            rtn = self.pointwise(i, 'total', temp)
            if rtn is None:
                continue
            sig_b += a * bins.pointwise_linear_collapse(e_n, rtn[0], rtn[1])
        return sig_b / self.atom_dens.get(nuc, 0.0)

    def _rank_ace_tables(self, nuc, temp=300.0):
        """Filters and sorts the potential ACE tables based on nucliude and
        temperature.
        """
        tabs = [t for t in self.cross_sections.ace_tables if t.nucid == nuc]
        if len(tabs) == 0:
            return tabs
        temps = {t.temperature for t in tabs}
        temps = sorted(temps, key=lambda s: abs(float(s) - temp * MeV_per_K))
        nearest_temp = temps[0]
        tabs = [t for t in tabs if t.temperature == nearest_temp]
        tabs.sort(reverse=True, key=lambda t: t.name)
        return tabs

    def load(self, temp=300.0):
        """Loads the entire data source into memory. This can be expensive for
        lots of ACE data.

        Parameters
        ----------
        temp : float, optional
            Temperature [K] of material, defaults to 300.0.

        """
        for atab in self.cross_sections.ace_tables:
            if os.path.isfile(atab.abspath or atab.path):
                lib = self.libs[atab] = ace.Library(atab.abspath or atab.path)
                lib.read(atab.name)
Example #32
0
def test_id_alts():
    assert_equal(rxname.id("alpha"), _hash("a"))
    assert_equal(rxname.id("tot"), _hash("total"))
Example #33
0
class EAFDataSource(DataSource):
    """European Activation File cross section data source.  The relevant EAF
    cross section data must be present in the nuc-data for this data source
    to exist.

    Parameters
    ----------
    kwargs : optional
        Keyword arguments to be sent to base class.

    Notes
    -----
    EAF data does not use temperature information.
    """

    # MT#s included in the EAF data
    _rx_avail = {
        rxname.id("gamma"): b"1020",
        rxname.id("gamma_1"): b"1021",
        rxname.id("gamma_2"): b"1022",
        rxname.id("p"): b"1030",
        rxname.id("p_1"): b"1031",
        rxname.id("p_2"): b"1032",
        rxname.id("d"): b"1040",
        rxname.id("d_1"): b"1041",
        rxname.id("d_2"): b"1042",
        rxname.id("t"): b"1050",
        rxname.id("t_1"): b"1051",
        rxname.id("t_2"): b"1052",
        rxname.id("He3"): b"1060",
        rxname.id("He3_1"): b"1061",
        rxname.id("He3_2"): b"1062",
        rxname.id("a"): b"1070",
        rxname.id("a_1"): b"1071",
        rxname.id("a_2"): b"1072",
        rxname.id("z_2a"): b"1080",
        rxname.id("z_2p"): b"1110",
        rxname.id("z_2p_1"): b"1111",
        rxname.id("z_2p_2"): b"1112",
        rxname.id("z_2n"): b"160",
        rxname.id("z_2n_1"): b"161",
        rxname.id("z_2n_2"): b"162",
        rxname.id("z_3n"): b"170",
        rxname.id("z_3n_1"): b"171",
        rxname.id("z_3n_2"): b"172",
        rxname.id("fission"): b"180",
        rxname.id("na"): b"220",
        rxname.id("na_1"): b"221",
        rxname.id("na_2"): b"222",
        rxname.id("z_2na"): b"240",
        rxname.id("np"): b"280",
        rxname.id("np_1"): b"281",
        rxname.id("np_2"): b"282",
        rxname.id("n2a"): b"290",
        rxname.id("nd"): b"320",
        rxname.id("nd_1"): b"321",
        rxname.id("nd_2"): b"322",
        rxname.id("nt"): b"330",
        rxname.id("nt_1"): b"331",
        rxname.id("nt_2"): b"332",
        rxname.id("nHe3"): b"340",
        rxname.id("nHe3_1"): b"341",
        rxname.id("nHe3_2"): b"342",
        rxname.id("z_4n"): b"370",
        rxname.id("z_4n_1"): b"371",
        rxname.id("n"): b"40",
        rxname.id("n_1"): b"41",
        rxname.id("n_2"): b"42",
        rxname.id("z_3np"): b"420",
    }

    _avail_rx = dict([_[::-1] for _ in _rx_avail.items()])

    _USES_TEMP = False

    def __init__(self, **kwargs):
        super(EAFDataSource, self).__init__(**kwargs)

    def _load_group_structure(self):
        """Loads the EAF energy bounds array, E_g, from nuc_data."""
        with tb.open_file(nuc_data, "r") as f:
            E_g = np.array(f.root.neutron.eaf_xs.E_g)
        self.src_group_struct = E_g

    @property
    def exists(self):
        if self._exists is None:
            with tb.open_file(nuc_data, "r") as f:
                self._exists = "/neutron/eaf_xs" in f
        return self._exists

    def _load_reaction(self, nuc, rx, temp=300.0):
        """Loads reaction specific data for EAF.

        Parameters
        ----------
        nuc : int
            Nuclide id.
        rx : int
            Reaction id.
        temp : float, optional
            The material temperature

        Notes
        -----
        EAF data does not use temperature information (temp).

        """
        absrx = rxname.id("absorption")

        if rx in self._rx_avail:
            if py3k is True:
                cond = "(nuc_zz == {0}) & (rxnum == {1})"
            else:
                cond = "(nuc_zz == {0}) & (rxnum == '{1}')"
            cond = cond.format(nuc, self._rx_avail[rx])
        elif rx == absrx:
            cond = "(nuc_zz == {0})".format(nuc)
        else:
            return None

        # Grab data
        with tb.open_file(nuc_data, "r") as f:
            node = f.root.neutron.eaf_xs.eaf_xs
            rows = node.read_where(cond)
            # rows = [np.array(row['xs']) for row in node.where(cond)]

        if len(rows) == 0:
            rxdata = None
        elif 1 < len(rows):
            xss = rows["xs"]
            rxnums = rows["rxnum"]
            for rxnum, xs in zip(rxnums, xss):
                self.rxcache[nuc, self._avail_rx[rxnum]] = xs
            rxdata = xss.sum(axis=0)
        else:
            rxdata = rows[0]["xs"]

        return rxdata

    def load(self, temp=300.0):
        """Loads all EAF into memory.

        Parameters
        ----------
        temp : float, optional
            The material temperature

        Notes
        -----
        EAF data does not use temperature information (temp).

        """
        rxcache = self.rxcache
        avail_rx = self._avail_rx
        absrx = rxname.id("absorption")
        with tb.open_file(nuc_data, "r") as f:
            node = f.root.neutron.eaf_xs.eaf_xs
            for row in node:
                nuc = row["nuc_zz"]
                rx = avail_rx[row["rxnum"]]
                xs = row["xs"]
                rxcache[nuc, rx] = xs
                abskey = (nuc, absrx)
                rxcache[abskey] = xs + rxcache.get(abskey, 0.0)
        self.fullyloaded = True
Example #34
0
class EAFDataSource(DataSource):
    """European Activation File cross section data source.  The relevant EAF
    cross section data must be present in the nuc-data for this data source
    to exist.

    Parameters
    ----------
    kwargs : optional
        Keyword arguments to be sent to base class.

    Notes
    -----
    EAF data does not use temperature information.
    """

    # MT#s included in the EAF data
    _rx_avail = {
        rxname.id('gamma'): b'1020',
        rxname.id('gamma_1'): b'1021',
        rxname.id('gamma_2'): b'1022',
        rxname.id('p'): b'1030',
        rxname.id('p_1'): b'1031',
        rxname.id('p_2'): b'1032',
        rxname.id('d'): b'1040',
        rxname.id('d_1'): b'1041',
        rxname.id('d_2'): b'1042',
        rxname.id('t'): b'1050',
        rxname.id('t_1'): b'1051',
        rxname.id('t_2'): b'1052',
        rxname.id('He3'): b'1060',
        rxname.id('He3_1'): b'1061',
        rxname.id('He3_2'): b'1062',
        rxname.id('a'): b'1070',
        rxname.id('a_1'): b'1071',
        rxname.id('a_2'): b'1072',
        rxname.id('z_2a'): b'1080',
        rxname.id('z_2p'): b'1110',
        rxname.id('z_2p_1'): b'1111',
        rxname.id('z_2p_2'): b'1112',
        rxname.id('z_2n'): b'160',
        rxname.id('z_2n_1'): b'161',
        rxname.id('z_2n_2'): b'162',
        rxname.id('z_3n'): b'170',
        rxname.id('z_3n_1'): b'171',
        rxname.id('z_3n_2'): b'172',
        rxname.id('fission'): b'180',
        rxname.id('na'): b'220',
        rxname.id('na_1'): b'221',
        rxname.id('na_2'): b'222',
        rxname.id('z_2na'): b'240',
        rxname.id('np'): b'280',
        rxname.id('np_1'): b'281',
        rxname.id('np_2'): b'282',
        rxname.id('n2a'): b'290',
        rxname.id('nd'): b'320',
        rxname.id('nd_1'): b'321',
        rxname.id('nd_2'): b'322',
        rxname.id('nt'): b'330',
        rxname.id('nt_1'): b'331',
        rxname.id('nt_2'): b'332',
        rxname.id('nHe3'): b'340',
        rxname.id('nHe3_1'): b'341',
        rxname.id('nHe3_2'): b'342',
        rxname.id('z_4n'): b'370',
        rxname.id('z_4n_1'): b'371',
        rxname.id('n'): b'40',
        rxname.id('n_1'): b'41',
        rxname.id('n_2'): b'42',
        rxname.id('z_3np'): b'420',
    }

    _avail_rx = dict([_[::-1] for _ in _rx_avail.items()])

    _USES_TEMP = False

    def __init__(self, **kwargs):
        super(EAFDataSource, self).__init__(**kwargs)

    def _load_group_structure(self):
        """Loads the EAF energy bounds array, E_g, from nuc_data."""
        with tb.openFile(nuc_data, 'r') as f:
            E_g = np.array(f.root.neutron.eaf_xs.E_g)
        self.src_group_struct = E_g

    @property
    def exists(self):
        if self._exists is None:
            with tb.openFile(nuc_data, 'r') as f:
                self._exists = ('/neutron/eaf_xs' in f)
        return self._exists

    def _load_reaction(self, nuc, rx, temp=300.0):
        """Loads reaction specific data for EAF.

        Parameters
        ----------
        nuc : int
            Nuclide id.
        rx : int
            Reaction id.
        temp : float, optional
            The material temperature

        Notes
        -----
        EAF data does not use temperature information (temp).

        """
        absrx = rxname.id('absorption')

        if rx in self._rx_avail:
            if py3k is True:
                cond = "(nuc_zz == {0}) & (rxnum == {1})"
            else:
                cond = "(nuc_zz == {0}) & (rxnum == '{1}')"
            cond = cond.format(nuc, self._rx_avail[rx])
        elif rx == absrx:
            cond = "(nuc_zz == {0})".format(nuc)
        else:
            return None

        # Grab data
        with tb.openFile(nuc_data, 'r') as f:
            node = f.root.neutron.eaf_xs.eaf_xs
            rows = node.readWhere(cond)
            #rows = [np.array(row['xs']) for row in node.where(cond)]

        if len(rows) == 0:
            rxdata = None
        elif 1 < len(rows):
            xss = rows['xs']
            rxnums = rows['rxnum']
            for rxnum, xs in zip(rxnums, xss):
                self.rxcache[nuc, self._avail_rx[rxnum]] = xs
            rxdata = xss.sum(axis=0)
        else:
            rxdata = rows[0]['xs']

        return rxdata

    def load(self, temp=300.0):
        """Loads all EAF into memory.

        Parameters
        ----------
        temp : float, optional
            The material temperature

        Notes
        -----
        EAF data does not use temperature information (temp).

        """
        rxcache = self.rxcache
        avail_rx = self._avail_rx
        absrx = rxname.id('absorption')
        with tb.openFile(nuc_data, 'r') as f:
            node = f.root.neutron.eaf_xs.eaf_xs
            for row in node:
                nuc = row['nuc_zz']
                rx = avail_rx[row['rxnum']]
                xs = row['xs']
                rxcache[nuc, rx] = xs
                abskey = (nuc, absrx)
                rxcache[abskey] = xs + rxcache.get(abskey, 0.0)
        self.fullyloaded = True
Example #35
0
class CinderDataSource(DataSource):
    """Cinder cross section data source. The relevant cinder cross section data must
    be present in the nuc_data for this data source to exist.  This data source does
    not use material temperature information.

    Parameters
    ----------
    kwargs : optional
        Keyword arguments to be sent to base class.

    """
    # 'h' stands for helion or 'He3'
    _rx_avail = {
        rxname.id('np_1'): 'np *',
        rxname.id('a_1'): 'a  *',
        rxname.id('He3_1'): 'h  *',
        rxname.id('z_2p_1'): '2p *',
        rxname.id('z_3n_1'): '3n *',
        rxname.id('d_1'): 'd  *',
        rxname.id('npd'): 'np/d',
        rxname.id('na'): 'na',
        rxname.id('excited'): '*',
        rxname.id('nd'): 'nd',
        rxname.id('gamma_1'): 'g  *',
        rxname.id('z_3n'): '3n',
        rxname.id('np'): 'np',
        rxname.id('nt'): 'nt',
        rxname.id('t'): 't',
        rxname.id('nt_1'): 'nt *',
        rxname.id('z_4n_1'): '4n *',
        rxname.id('na_1'): 'na *',
        rxname.id('nd_1'): 'nd *',
        rxname.id('t_1'): 't  *',
        rxname.id('a'): 'a',
        rxname.id('z_2p'): '2p',
        rxname.id('d'): 'd',
        rxname.id('gamma'): 'g',
        rxname.id('He3'): 'h',
        rxname.id('n'): 'n',
        rxname.id('z_4n'): '4n',
        rxname.id('p'): 'p',
        rxname.id('n_1'): 'n  *',
        rxname.id('z_2a'): '2a',
        rxname.id('z_2n_1'): '2n *',
        rxname.id('z_2n'): '2n',
        rxname.id('nHe3_1'): 'nh *',
        rxname.id('p_1'): 'p  *',
        # not real or unique absorption reactions
        #rxname.id(''): "",
        #rxname.id(''): 'x',
        #rxname.id(''): 'x  *',
        #rxname.id(''): 'c',
        #rxname.id('fission'): 'f',
    }

    _USES_TEMP = False

    def __init__(self, **kwargs):
        super(CinderDataSource, self).__init__(**kwargs)

    def _load_group_structure(self):
        """Loads the cinder energy bounds array, E_g, from nuc_data."""
        with tb.openFile(nuc_data, 'r') as f:
            E_g = np.array(f.root.neutron.cinder_xs.E_g)
        self.src_group_struct = E_g

    @property
    def exists(self):
        if self._exists is None:
            with tb.openFile(nuc_data, 'r') as f:
                self._exists = ('/neutron/cinder_xs' in f)
        return self._exists

    def _load_reaction(self, nuc, rx, temp=300.0):
        fissrx = rxname.id('fission')
        absrx = rxname.id('absorption')

        # Set query condition
        if rx in self._rx_avail:
            if py3k:
                cond = "(from_nuc == {0}) & (reaction_type == {1})"
            else:
                cond = "(from_nuc == {0}) & (reaction_type == '{1}')"
            cond = cond.format(nuc, self._rx_avail[rx].encode())
        elif rx == fissrx:
            cond = 'nuc == {0}'.format(nuc)
        elif rx == absrx:
            cond = "(from_nuc == {0}) & (reaction_type != b'c')".format(nuc)
        else:
            return None

        # read & collapse data
        with tb.openFile(nuc_data, 'r') as f:
            node = f.root.neutron.cinder_xs.fission if rx == fissrx else \
                   f.root.neutron.cinder_xs.absorption
            rows = [np.array(row['xs']) for row in node.where(cond)]

        if 1 == len(rows):
            rxdata = rows[0]
        elif 1 < len(rows):
            rows = np.array(rows)
            rxdata = rows.sum(axis=0)
        else:
            rxdata = None

        # add fission data to absorption
        if rx == absrx:
            fdata = self._load_reaction(nuc, fissrx)
            if fdata is not None:
                rxdata = fdata if rxdata is None else rxdata + fdata
        return rxdata
Example #36
0
def test_id_nucdelta():
    assert_equal(rxname.id("U235", "U236"), _hash("absorption"))
    assert_equal(rxname.id("U235", "Np236", "p"), _hash("absorption"))
    assert_equal(rxname.id(922350, 912350), _hash("p"))
Example #37
0
def levels(filename, levellist=None, lmap=None, lcount=0):
    badlist = [
        "ecsf", "34si", "|b{+-}fission", "{+24}ne", "{+22}ne", "24ne", "b-f",
        "{+20}o", "2|e", "b++ec", "ecp+ec2p", "ecf", "mg", "ne", "{+20}ne",
        "{+25}ne", "{+28}mg", "sf(+ec+b+)"
    ]
    special = ""
    if levellist is None:
        levellist = []
    if lmap is None:
        lmap = dict()
    if isinstance(filename, str):
        with open(filename, 'r') as f:
            dat = f.read()
    else:
        dat = filename.read()
    datasets = dat.split(80 * " " + "\n")[0:-1]
    for dataset in datasets:
        lines = dataset.splitlines()
        ident = re.match(_ident, lines[0])
        if ident is None:
            continue
        if 'ADOPTED LEVELS' in ident.group(2):
            leveln = 0
            brs = {}
            level_found = False
            for line in lines:
                level_l = _level_regex.match(line)
                if level_l is not None:
                    if len(brs) > 0:
                        for key, val in brs.items():
                            goodkey = True
                            keystrip = key.replace("%", "").lower()
                            for item in badlist:
                                if keystrip == item:
                                    goodkey = False
                            if goodkey is True:
                                rx = rxname.id(keystrip)
                                levellist.append(
                                    (nuc_id, rx, half_lifev, level,
                                     val.split("(")[0], state, special))
                    if level_found is True:
                        levellist.append((nuc_id, 0, half_lifev, level, 0.0,
                                          state, special))
                    brs = {}
                    level, half_lifev, from_nuc, state, special = \
                        _parse_level_record(level_l)
                    if from_nuc is not None:
                        nuc_id = from_nuc + leveln
                        if leveln == 0:
                            lmap.update({nuc_id: lcount})
                        leveln += 1
                        lcount += 1
                        level_found = True
                    else:
                        level_found = False
                    continue
                levelc = _level_cont_regex.match(line)
                if levelc is not None:
                    brs.update(_parse_level_continuation_record(levelc))
                    continue
            if len(brs) > 0:
                for key, val in brs.items():
                    goodkey = True
                    keystrip = key.replace("%", "").lower()
                    for item in badlist:
                        if keystrip == item:
                            goodkey = False
                    if goodkey is True:
                        rx = rxname.id(keystrip)
                        levellist.append((nuc_id, rx, half_lifev, level,
                                          val.split("(")[0], state, special))
            if level_found is True:
                levellist.append(
                    (nuc_id, 0, half_lifev, level, 0.0, state, special))
    return levellist