Example #1
0
 def write_metadata(self, nucs, libs, dirname):
     track_actinides = [n for n in nucs if nucname.znum(n) in nucname.act]
     with open(os.path.join(dirname, "manifest.txt"), "w") as f:
         f.write("\n".join([str(nucname.zzaaam(act)) for act in track_actinides]))
         f.write("\n")
     with open(os.path.join(dirname, "params.txt"), "w") as f:
         if self.rc.get("enrichment") is None:
             enrichment = self.rc.initial_heavy_metal.get(922350)
         else:
             enrichment = self.rc.enrichment
         if enrichment is not None:
             f.write("ENRICHMENT {}\n".format(enrichment))
         if self.rc.get("batches") is not None:
             f.write("BATCHES {}\n".format(self.rc.batches))
         if self.rc.get("pnl") is not None:
             f.write("PNL {}\n".format(self.rc.pnl))
         f.write("BURNUP {}\n".format(sum(libs["fuel"]["BUd"])))
         f.write("FLUX {:.0E}\n".format(np.mean(libs["fuel"]["phi_tot"][1:])))
     with open(os.path.join(dirname, "structural.txt"), "w") as f:
         clad_linear_density = pi * self.rc.clad_density * \
             (self.rc.clad_cell_radius ** 2 - self.rc.void_cell_radius ** 2)
         fuel_linear_density = pi * self.rc.fuel_density * \
             self.rc.fuel_cell_radius ** 2
         clad_frac = float(clad_linear_density / fuel_linear_density)
         cladrows = ["{} {:.8f}".format(nucname.zzaaam(n), f*clad_frac)
                     for n, f in self.rc.clad_material.comp.items()]
         f.write("\n".join(cladrows))
         f.write("\n")
     shutil.copyfile("TAPE9.INP", os.path.join(dirname, "TAPE9.INP"))
Example #2
0
def parse_nucs(s):
    """Parses a string into a set of nuclides."""
    nset = set()
    nucs = s.split(',')

    for nuc in nucs:
        if len(nuc) == 0:
            continue
        elif '-' in nuc:
            nsplit = nuc.split()
            nlower = nucname.zzaaam(nsplit[0])
            nupper = nucname.zzaaam(nsplit[1])
            if 0 == nupper%10000:
                nupper += 10000
            else:
                nupper += 1
            tmpset = set(range(nlower, nupper))
        else:
            n = nucname.zzaaam(nuc)
            if 0 == n%10000:
                nrange = range(n, n + 10000)
            else:
                nrange = [n]
            tmpset = set(nrange)

        # Add the union 
        nset = (nset | tmpset)

    return nset
Example #3
0
def metastable_ratio(nuc, rx, temp=300.0, group_struct=None, phi_g=None, xs_cache=None):
    """Calculates the ratio between a reaction that leaves the nuclide in a 
    metastable state and the equivalent reaction that leaves the nuclide in 
    the ground state.  This allows the calculation of metastable cross sections 
    via sigma_ms = ratio * sigma_ground. 

    Parameters
    ----------
    nuc : int, str, Material, or dict-like 
        A nuclide or nuclide-atom fraction mapping.
    rx : str
        Reaction key. ('gamma', 'alpha', 'p', etc.)
    temp : float, optional
        Temperature [K] of material, defaults to 300.0.
    group_struct : array-like of floats, optional
        Energy group structure E_g [MeV] from highest-to-lowest energy, length G+1,
        defaults to xs_cache['E_g'].
    phi_g : array-like of floats, optional
        Group fluxes [n/cm^2/s] matching group_struct, length G, defaults to 
        xs_cache['phi_g'].
    xs_cache : XSCache, optional
        Cross section cache to use, defaults to pyne.xs.cache.xs_cache. 

    Returns
    -------
    ratio_rx_g : ndarray
        An array of the ratio of the metastable cross section for a reaction 
        to the ground state reaction.

    Notes
    -----
    This always pulls the absorption reaction cross section out of the cache.

    See Also
    --------
    pyne.xs.data_source.RX_TYPES
    pyne.xs.data_source.RX_TYPES_MAP 

    """
    if isinstance(nuc, int) or isinstance(nuc, basestring):
        xs_cache = cache.xs_cache if xs_cache is None else xs_cache
        _prep_cache(xs_cache, group_struct, phi_g)
        nuc = nucname.zzaaam(nuc)
        key = (nuc, rx + "_x_ratio", temp)
        if key in xs_cache:
            return xs_cache[key]

    # Get the cross-sections
    sigma_rx = sigma_a_reaction(nuc, rx, temp, group_struct, phi_g, xs_cache)
    sigma_rx_x = sigma_a_reaction(nuc, rx + "_x", temp, group_struct, phi_g, xs_cache)

    # Get the ratio
    ratio_rx_g = sigma_rx_x / sigma_rx
    ratio_rx_g[ratio_rx_g < 0.0] = 0.0
    ratio_rx_g[ratio_rx_g == np.inf] = 0.0
    ratio_rx_g[np.isnan(ratio_rx_g)] = 0.0

    if isinstance(nuc, int):
        xs_cache[key] = ratio_rx_g
    return ratio_rx_g
Example #4
0
def sigma_f(nuc, temp=300.0, group_struct=None, phi_g=None, xs_cache=None):
    """Calculates the neutron fission cross section for a nuclide. 

    Parameters
    ----------
    nuc : int, str, Material, or dict-like 
        A nuclide or nuclide-atom fraction mapping.
    temp : float, optional
        Temperature [K] of material, defaults to 300.0.
    group_struct : array-like of floats, optional
        Energy group structure E_g [MeV] from highest-to-lowest energy, length G+1,
        defaults to xs_cache['E_g'].
    phi_g : array-like of floats, optional
        Group fluxes [n/cm^2/s] matching group_struct, length G, defaults to 
        xs_cache['phi_g'].
    xs_cache : XSCache, optional
        Cross section cache to use, defaults to pyne.xs.cache.xs_cache. 

    Returns
    -------
    sigma_f_g : ndarray 
        The fission cross-section, length G.

    Notes
    -----
    This always pulls the fission cross section out of the cache.

    """
    xs_cache = cache.xs_cache if xs_cache is None else xs_cache
    _prep_cache(xs_cache, group_struct, phi_g)
    if isinstance(nuc, collections.Iterable) and not isinstance(nuc, basestring):
        return _atom_weight_channel(sigma_f, nuc, temp=temp, xs_cache=xs_cache)
    nuc = nucname.zzaaam(nuc)
    key = (nuc, "f", temp)
    return xs_cache[key]
def make_1g_xs_graphs(nuc, sig):
    global burn_times
    nuc_zz = nucname.zzaaam(nuc)
    plt.clf()

    reactions = ['sigma_t', 'sigma_s', 'sigma_a', 'sigma_f']
    markers = ['-', 'o', 's', 'x']
    ncol = 2

    if nuc_zz < 860000:
        reactions = reactions[:-1]
        markers = markers[:-1]
        ncol = 3

    for reaction, marker in zip(reactions, markers):
        r, s, diff = sig[reaction, nuc]
        plt.plot(burn_times, s, color='k', marker=marker, linestyle='-', label="Serpent $\\{0}$".format(reaction))
        #plt.errorbar(burn_times, r, diff*r, color='r', marker=marker, linestyle='-', label="RMG $\\{0}$".format(reaction))
        plt.plot(burn_times, r, color='r', marker=marker, linestyle='-', label="RMG $\\{0}$".format(reaction))

    plt.xlabel("burn time [days]")
    plt.ylabel(nuc + " One-Group Cross Sections [barns]")
    plt.ticklabel_format(scilimits=(-5, 5))
    plt.legend(loc=0, ncol=ncol)
    plt.savefig(nuc + '_1g_xs.png')
    plt.savefig(nuc + '_1g_xs.eps')
    plt.clf()
Example #6
0
    def update(self, libs, dirname, fname):
        rownames = ["TIME", "phi_tot", "NEUT_PROD", "NEUT_DEST", "BUd"]
        trans_matrix = {}
        for mat, matlib in libs.items():
            if isinstance(mat, int):
                fname = str(nucname.zzaaam(mat))
            elif mat == 'fuel':
                fname = mat
            else:
                continue
            f = open(os.path.join(dirname, fname + ".txt"), "r")         
            lines = f.readlines()
            time_steps = len(lines[0].split())
            i = 5
            while i < range(len(lines)):
                nuc_array = lines[i].split()
                nuc_name = nuc_array[0]
                nuc_values = nuc_array[1:]
                if len(nuc_array) == time_steps:
                    trans_matrix[nuc_name] = nuc_values
                    trans_matrix[nuc_name].append(matlib['material'][-1].comp[temp_nuc]*1000)
                else:
                    if matlib['material'][-1].comp[nuc_name] > self.rc.track_nuc_threshold:
                        zero_array = [0.]*(time_steps-1)
                        trans_matrix[nuc_name] = zero_array
                        trans_matrix[nuc_name].append(matlib['material'][-1].comp[temp_nuc]*1000)
                i+=1;
            if time_steps == len(matlib['TIME']):
                return libs, trans_matrix
            for j in range(len(rownames)):
                store = matlib[rownames[j]][-1]
                matlib[rownames[j]] = lines[j].split()[1:]
                matlib[rownames[j]].append(store)

        return libs, trans_matrix    
Example #7
0
    def write_mat_file(self, dep_dict, mat_file, cumulative_time_at_eds):
        """Writes the iteration input file containing burnable materials
        composition used in depletion runs and updated after each depletion
        step.

        Parameters
        ----------
        mats : dict
            Dictionary that contains `Materialflow` objects.

            ``key``
                Name of burnable material.
            ``value``
                `Materialflow` object holding composition and properties.
        mat_file : str
            Path to file containing burnable materials composition.
        cumulative_time_at_eds : float
            Current time at the end of the depletion step (d).

        """

        matf = open(mat_file, 'w')
        matf.write('%% Material compositions (after %f days)\n\n' %
                   cumulative_time_at_eds)
        for key, value in dep_dict.items():
            matf.write('mat  %s  %5.9E burn 1 fix %3s %4i vol %7.5E\n' %
                       (key, -dep_dict[key].density, '09c', dep_dict[key].temp,
                        dep_dict[key].vol))
            for nuc_code, wt_frac in dep_dict[key].comp.items():
                # Transforms iso name from zas to zzaaam and then to SERPENT
                iso_name_serpent = pyname.zzaaam(nuc_code)
                matf.write('           %9s  %7.14E\n' %
                           (self.iso_map[iso_name_serpent], -wt_frac))
        matf.close()
def test_FuelFabrication_7():
    # Reactor to use
    rp = ReactorParameters()
    r1g = Reactor1G(rp=rp, n="r1g")

    # Mass streams to use
    u235 = Material({922350: 1.0}, 1.0, name="U-235")
    u238 = Material({922380: 1.0}, 1.0, name="U-238")
    mats = {"U235": u235, "U238": u238}

    # Mass weights to use
    mws = {"U235": -1.0, "U238": -1.0}

    # Fuel Fabrication Facility
    ff = FuelFabrication(mats=mats, mws_in=mws, r=r1g, paramtrack=set(["Mass"]), n="ff")

    keys = ["U235", "U238"]
    assert_equal(set(ff.materials.keys()), set(keys))

    for iso in keys:
        assert_equal(ff.materials[iso].mass, 1.0)
        assert_equal(ff.materials[iso].comp[nucname.zzaaam(iso)], 1.0)

    assert_equal(ff.mass_weights_in, mws)

    assert_equal(ff.track_params, set(["Mass", "Weight_U235", "deltaR_U235", "Weight_U238", "deltaR_U238"]))

    assert_equal(ff.name, "ff")

    assert_equal(ff.reactor.name, "r1g")
    r1g.name = "r1g name"
    ff.initialize(mats, mws, r1g)
    assert_equal(ff.reactor.name, "r1g name")
Example #9
0
def parse_scattering_lengths(build_dir):
    """Converts to scattering lenth data to a numpy array."""
    build_filename = os.path.join(build_dir, "scattering_lengths.html")
    
    # Read in cinder data file
    with open(build_filename, 'r') as f:
        raw_data = f.read()

    sl_data = []

    # Iterate over all isotopes in the table
    for m in re.finditer(scat_len_pattern, raw_data):
        md = m.groupdict()

        slrow = (nucname.zzaaam(md['iso']),
                 nist_num(md['b_coherent']) * (1E-13),
                 nist_num(md['b_incoherent']) * (1E-13),
                 nist_num(md['xs_coherent']),
                 nist_num(md['xs_incoherent']),
                 nist_num(md['xs']))

        sl_data.append(slrow)

    sl_array = np.array(sl_data, dtype=sl_dtype)
    return sl_array
Example #10
0
def make_atomic_weight_table(nuc_data, build_dir=""):
    """Makes an atomic weight table in the nuc_data library.

    Parameters
    ----------
    nuc_data : str
        Path to nuclide data file.
    build_dir : str
        Directory to place html files in.
    """
    # Grab raw data
    atomic_abund = parse_atomic_abund(build_dir)
    atomic_masses = parse_atmoic_mass_adjustment(build_dir)

    A = {}

    # Add normal isotopes to A
    for nuc_zz, mass, error in atomic_masses:
        try:
            nuc_name = nucname.name(nuc_zz)
        except RuntimeError:
            continue

        if nuc_zz in atomic_abund:
            A[nuc_zz] = nuc_name, nuc_zz, mass, error, atomic_abund[nuc_zz]
        else:
            A[nuc_zz] = nuc_name, nuc_zz, mass, error, 0.0

    # Add naturally occuring elements
    for element in nucname.name_zz:
        nuc_zz = nucname.zzaaam(element)
        A[nuc_zz] = element, nuc_zz, 0.0, 0.0, 0.0

    for nuc, abund in atomic_abund.items():
        zz = nuc / 10000
        element_zz = zz * 10000
        element = nucname.zz_name[zz]

        nuc_name, nuc_zz, nuc_mass, _error, _abund = A[nuc]
        elem_name, elem_zz, elem_mass, _error, _abund = A[element_zz]

        new_elem_mass = elem_mass + (nuc_mass * abund)
        A[element_zz] = element, element_zz, new_elem_mass, 0.0, 0.0

    A = sorted(A.values(), key=lambda x: x[1])
    # A = np.array(A, dtype=atomic_weight_dtype)

    # Open the HDF5 File
    kdb = tb.openFile(nuc_data, "a", filters=BASIC_FILTERS)

    # Make a new the table
    Atable = kdb.createTable("/", "atomic_weight", atomic_weight_desc, "Atomic Weight Data [amu]", expectedrows=len(A))
    Atable.append(A)

    # Ensure that data was written to table
    Atable.flush()

    # Close the hdf5 file
    kdb.close()
Example #11
0
def sigma_a_reaction(nuc, rx, E_g=None, E_n=None, phi_n=None):
    """Calculates the neutron absorption reaction cross-section for a nuclide for a 
    new, lower resolution group structure using a higher fidelity flux.  Note that 
    g indexes G, n indexes N, and G < N.

    Parameters
    ----------
    nuc : int, str, Material, or dict-like 
        A nuclide or nuclide-atom fraction mapping for which to calculate the 
        absorption reaction cross-section.
    rx : str
        Reaction key. ('gamma', 'alpha', 'p', etc.)
    E_g : array-like of floats, optional
        New, lower fidelity energy group structure [MeV] that is of length G+1. 
    E_n : array-like of floats, optional
        Higher resolution energy group structure [MeV] that is of length N+1. 
    phi_n : array-like of floats, optional
        The high-fidelity flux [n/cm^2/s] to collapse the fission cross-section over.  
        Length N.  

    Returns
    -------
    sigma_rx_g : ndarray 
        An array of the collapsed absorption reaction cross section.

    Notes
    -----
    This always pulls the absorption reaction cross-section out of the nuc_data.    

    See Also
    --------
    pyne.xs.cache.ABSORPTION_RX
    pyne.xs.cache.ABSORPTION_RX_MAP 
    """
    _prep_cache(E_g, E_n, phi_n)

    if isinstance(nuc, collections.Iterable) and not isinstance(nuc, basestring):
        return _atom_weight_channel(sigma_a_reaction, nuc, rx)

    # Get the absorption XS
    nuc_zz = nucname.zzaaam(nuc)
    key_n = ('sigma_rx_n', nuc_zz, rx)
    key_g = ('sigma_rx_g', nuc_zz, rx)

    # Don't recalculate anything if you don't have to
    if key_g in xs_cache:
        return xs_cache[key_g]
    else:
        sigma_rx_n = xs_cache[key_n]

    # Perform the group collapse, knowing that the right data is in the cache
    sigma_rx_g = group_collapse(sigma_rx_n, xs_cache['phi_n'], phi_g=xs_cache['phi_g'], 
                                partial_energies=xs_cache['partial_energy_matrix'])

    # Put this value back into the cache, with the appropriate label
    xs_cache[key_g] = sigma_rx_g

    return sigma_rx_g
Example #12
0
def load_nuc_file(path):
    """Takes a file that contains whitespace separated nuclide names and
    returns the zzaaam representation as a sorted list."""
    with open(path, 'r') as f:
        s = f.read()

    nuc_list = [nucname.zzaaam(nuc) for nuc in s.split()]
    nuc_list.sort()
    return nuc_list
Example #13
0
def parse_for_all_isotopes(htmlfile):
    """Parses an elemental html file, returning a set of all occuring isotopes."""
    isos = set()
    with open(htmlfile, 'r') as f:
        for line in f:
            m = all_iso_regex.search(line)
            if m is not None:
                isos.add(nucname.zzaaam(m.group(1)))
    return isos
Example #14
0
def parse_for_all_isotopes(htmlfile):
    """Parses an elemental html file, returning a set of all occuring isotopes."""
    isos = set()
    with open(htmlfile, 'r') as f:
        for line in f:
            m = all_iso_regex.search(line)
            if m is not None:
                isos.add(nucname.zzaaam(m.group(1)))
    return isos
Example #15
0
def make_atomic_weight_table(nuc_data, build_dir=""):
    """Makes an atomic weight table in the nuc_data library.

    Parameters
    ----------
    nuc_data : str
        Path to nuclide data file.
    build_dir : str
        Directory to place html files in.
    """
    # Grab raw data
    atomic_abund = parse_atomic_abund(build_dir)
    atomic_masses = parse_atmoic_mass_adjustment(build_dir)

    A = {}

    # Add normal isotopes to A
    for nuc, mass, error in atomic_masses:
        if nuc in atomic_abund:
            A[nuc] = nuc, mass, error, atomic_abund[nuc]
        else:
            A[nuc] = nuc, mass, error, 0.0

    # Add naturally occuring elements
    for element in nucname.name_zz:
        nuc = nucname.zzaaam(element)
        A[nuc] = nuc, 0.0, 0.0, 1.0

    for nuc, abund in atomic_abund.items():
        zz = nuc / 10000
        element_zz = zz * 10000
        element = nucname.zz_name[zz]

        _nuc, nuc_mass, _error, _abund = A[nuc]
        elem_zz, elem_mass, _error, _abund = A[element_zz]

        new_elem_mass = elem_mass + (nuc_mass * abund)
        A[element_zz] = element_zz, new_elem_mass, 0.0, 1.0

    A = sorted(A.values(), key=lambda x: x[0])

    # Open the HDF5 File
    kdb = tb.openFile(nuc_data, 'a', filters=BASIC_FILTERS)

    # Make a new the table
    Atable = kdb.createTable("/",
                             "atomic_weight",
                             atomic_weight_desc,
                             "Atomic Weight Data [amu]",
                             expectedrows=len(A))
    Atable.append(A)

    # Ensure that data was written to table
    Atable.flush()

    # Close the hdf5 file
    kdb.close()
Example #16
0
def sigma_t(nuc, T=300.0, E_g=None, E_n=None, phi_n=None):
    """Calculates the total neutron cross section for a nuclide. 

    .. math::
        \\sigma_{t, g} = \\sigma_{a, g} + \\sigma_{s, g}

    Parameters
    ----------
    nuc : int, str, Material, or dict-like 
        A nuclide or nuclide-atom fraction mapping for which to calculate the 
        total cross section.
    T : float, optional
        Tempurature of the target material [kelvin].
    E_g : array-like of floats, optional
        New, lower fidelity energy group structure [MeV] that is of length G+1. 
    E_n : array-like of floats, optional
        Higher resolution energy group structure [MeV] that is of length N+1. 
    phi_n : array-like of floats, optional
        The high-fidelity flux [n/cm^2/s] to collapse the fission cross-section over.  
        Length N.  

    Returns
    -------
    sig_t_g : ndarray 
        An array of the total cross section.

    """
    _prep_cache(E_g, E_n, phi_n)

    if isinstance(nuc, collections.Iterable) and not isinstance(nuc, basestring):
        return _atom_weight_channel(sigma_t, nuc, T)

    # Get the total XS
    nuc_zz = nucname.zzaaam(nuc)
    key_a = ('sigma_a_g', nuc_zz)
    key_s = ('sigma_t_g', nuc_zz, T)
    key_t = ('sigma_t_g', nuc_zz, T)

    # Don't recalculate anything if you don't have to
    if key_t in xs_cache:
        return xs_cache[key_t]

    # This calculation requires the abosorption cross-section
    if key_a not in xs_cache:
        xs_cache[key_a] = sigma_a(nuc, E_g, E_n, phi_n)

    # This calculation requires the scattering cross-section
    if key_s not in xs_cache:
        xs_cache[key_s] = sigma_s(nuc, T, E_g, E_n, phi_n)

    # Sum over all h indeces
    sig_t_g = xs_cache[key_a] + xs_cache[key_s]

    # Put this value back into the cache, with the appropriate label
    xs_cache[key_t] = sig_t_g
    return sig_t_g
Example #17
0
def _to_zzaaam(nuc, m, s):
    nuc_zz = nucname.zzaaam(nuc.strip())
    if m == 'M':
        state = s.strip()
        if 0 < len(state):
            state = int(state)
        else:
            state = 1
        nuc_zz += state
    return nuc_zz
Example #18
0
def _to_zzaaam(nuc, m, s):
    nuc_zz = nucname.zzaaam(nuc.strip())
    if m == 'M':
        state = s.strip()
        if 0 < len(state):
            state = int(state)
        else:
            state = 1
        nuc_zz += state
    return nuc_zz
Example #19
0
def sigma_f(nuc, E_g=None, E_n=None, phi_n=None):
    """Calculates the neutron fission cross-section for a nuclide for a new, 
    lower resolution group structure using a higher fidelity flux.  Note that 
    g indexes G, n indexes N, and G < N.  If any of these are None-valued, 
    values from the cache are used.  The energy groups and fluxes are normally 
    ordered from highest-to-lowest energy.

    Parameters
    ----------
    nuc : int, str, Material, or dict-like 
        A nuclide or nuclide-atom fraction mapping for which to calculate the 
        fission cross-section.
    E_g : array-like of floats, optional
        New, lower fidelity energy group structure [MeV] that is of length G+1. 
    E_n : array-like of floats, optional
        Higher resolution energy group structure [MeV] that is of length N+1. 
    phi_n : array-like of floats, optional
        The high-fidelity flux [n/cm^2/s] to collapse the fission cross-section over.  
        Length N.  

    Returns
    -------
    sigma_f_g : ndarray 
        An array of the collapsed fission cross-section.

    Notes
    -----
    This always pulls the fission cross-section out of nuc_data library.    

    """
    _prep_cache(E_g, E_n, phi_n)

    if isinstance(nuc, collections.Iterable) and not isinstance(nuc, basestring):
        return _atom_weight_channel(sigma_f, nuc)

    # Get the fission XS
    nuc_zz = nucname.zzaaam(nuc)
    sigma_f_n_nuc_zz = ('sigma_f_n', nuc_zz)
    sigma_f_g_nuc_zz = ('sigma_f_g', nuc_zz)

    # Don't recalculate anything if you don't have to
    if sigma_f_g_nuc_zz in xs_cache:
        return xs_cache[sigma_f_g_nuc_zz]
    else:
        sigma_f_n = xs_cache[sigma_f_n_nuc_zz]

    # Perform the group collapse, knowing that the right data is in the cache
    sigma_f_g = group_collapse(sigma_f_n, xs_cache['phi_n'], phi_g=xs_cache['phi_g'], 
                               partial_energies=xs_cache['partial_energy_matrix'])

    # Put this value back into the cache, with the appropriate label
    xs_cache[sigma_f_g_nuc_zz] = sigma_f_g

    return sigma_f_g
Example #20
0
    def _load_reaction(self, nuc, rx, temp=300.0):
        """ 
        Note: EAF data does not use temperature information (temp)

        Parameters
        ----------
        nuc : int
            Nuclide in zzaaam form.
        rx : str 
            Reaction MT # in nnnm form.
            OR: (eventually)
            Reaction key: 'gamma', 'alpha', 'p', etc.

        See Also
        --------
        EAF_RX : list
            List of valid MT #s in the EAF data.
        EAF_RX_MAP : dict
            Dictionary for converting string reaction identifiers to MT #s.

        """
        nuc = nucname.zzaaam(nuc)

        # Munging the rx to an MT#
        try:
            int(rx)
        except ValueError:
            try:
                rx = EAF_RX_MAP[rx]
            except KeyError:
                pass

        # Check if usable rx #
        if rx is None:
            return None
        if str(rx) not in EAF_RX:
            msg = "the reaction '{rx}' is not valid.".format(rx=rx)
            raise IndexError(msg)

        # Grab data
        with tb.openFile(nuc_data, 'r') as f:
            cond = "(nuc_zz == {0}) & (rxnum == '{1}')".format(nuc, rx)
            node = f.root.neutron.eaf_xs.eaf_xs
            rows = [np.array(row['xs']) for row in node.where(cond)]

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

        return rxdata
Example #21
0
 def elemental_row(row):
     if re.match('[A-Z][a-z]?-?(\d{1,3})?$', row[0]):
         element = nucname.zzaaam(row[0])
         weight_frac = row[3]
         if nucname.name(element) in elemental_mats:
             composition.update(elemental_mats[row[0].upper()])
         else:
             composition[element] = float(weight_frac)
         nuc_zz.add(element)
     else:
         pass
def test_materials():
    keys = ["U235", "U238"]
    assert_equal(set(ff.materials.keys()), set(keys))

    for iso in keys:
        assert_equal(ff.materials[iso].mass, 1.0)
        assert_equal(ff.materials[iso].comp[nucname.zzaaam(iso)], 1.0)

    u235 = Material({922350: 1.0}, 1.0, name="U-235")
    u238 = Material({922380: 1.0}, 1.0, name="U-238")
    o16  = Material({80160:  1.0}, 1.0, name="O-16")
    mats = {"U235": u235, "U238": u238, "O16": o16}
    ff.materials = mats

    keys = ["U235", "U238", "O16"]
    assert_equal(set(ff.materials.keys()), set(keys))

    for iso in keys:
        assert_equal(ff.materials[iso].mass, 1.0)
        assert_equal(ff.materials[iso].comp[nucname.zzaaam(iso)], 1.0)
Example #23
0
def sigma_a_reaction(nuc,
                     rx,
                     temp=300.0,
                     group_struct=None,
                     phi_g=None,
                     xs_cache=None):
    """Calculates the neutron absorption reaction cross section for a nuclide.

    Parameters
    ----------
    nuc : int, str, Material, or dict-like 
        A nuclide or nuclide-atom fraction mapping.
    rx : str
        Reaction key. ('gamma', 'alpha', 'p', etc.)
    temp : float, optional
        Temperature [K] of material, defaults to 300.0.
    group_struct : array-like of floats, optional
        Energy group structure E_g [MeV] from highest-to-lowest energy, length G+1,
        defaults to xs_cache['E_g'].
    phi_g : array-like of floats, optional
        Group fluxes [n/cm^2/s] matching group_struct, length G, defaults to 
        xs_cache['phi_g'].
    xs_cache : XSCache, optional
        Cross section cache to use, defaults to pyne.xs.cache.xs_cache. 

    Returns
    -------
    sigma_rx_g : ndarray 
        The collapsed absorption reaction cross section, length G.

    Notes
    -----
    This always pulls the absorption reaction cross-section out of the nuc_data.    

    See Also
    --------
    pyne.xs.data_source.RX_TYPES
    pyne.xs.data_source.RX_TYPES_MAP 

    """
    xs_cache = cache.xs_cache if xs_cache is None else xs_cache
    _prep_cache(xs_cache, group_struct, phi_g)
    if isinstance(nuc,
                  collections.Iterable) and not isinstance(nuc, basestring):
        return _atom_weight_channel(sigma_a_reaction,
                                    nuc,
                                    rx=rx,
                                    temp=temp,
                                    xs_cache=xs_cache)
    nuc = nucname.zzaaam(nuc)
    key = (nuc, rx, temp)
    return xs_cache[key]
Example #24
0
def test_sigma_s():
    if not hasattr(rx_h5.root, 'sigma_s'):
        raise nose.SkipTest

    for nuc in nucs:    
        nuc_zz = nucname.zzaaam(nuc)

        sig_t_arr, sig_t = read_array(rx_h5.root.sigma_t, nuc)
        sig_s_arr, sig_s = read_array(rx_h5.root.sigma_s, nuc)
        sig_s_gh_arr, sig_s_gh = read_array(rx_h5.root.sigma_s_gh, nuc)

        yield check_le, sig_s, sig_t, [sig_s_arr._v_pathname, sig_t_arr._v_pathname]
        yield check_array_almost_eq, sig_s, sig_s_gh.sum(axis=-2), [sig_s_arr._v_pathname, 'sum(' + sig_s_gh_arr._v_pathname + ')']
Example #25
0
def sigma_s(nuc, T, E_g=None, E_n=None, phi_n=None):
    """Calculates the neutron scattering cross-section for a nuclide. 

    .. math::
        \\sigma_{s, g} = \\sum_{h} \\sigma_{s, g\\to h} 

    Parameters
    ----------
    nuc : int, str, Material, or dict-like 
        A nuclide or nuclide-atom fraction mapping for which to calculate the 
        scattering cross section.
    T : float
        Tempurature of the target material [kelvin].
    E_g : array-like of floats, optional
        New, lower fidelity energy group structure [MeV] that is of length G+1. 
    E_n : array-like of floats, optional
        Higher resolution energy group structure [MeV] that is of length N+1. 
    phi_n : array-like of floats, optional
        The high-fidelity flux [n/cm^2/s] to collapse the fission cross-section over.  
        Length N.  

    Returns
    -------
    sig_s_g : ndarray 
        An array of the scattering cross section.

    """
    _prep_cache(E_g, E_n, phi_n)

    if isinstance(nuc, collections.Iterable) and not isinstance(nuc, basestring):
        return _atom_weight_channel(sigma_s, nuc, T)

    nuc_zz = nucname.zzaaam(nuc)
    key_g = ('sigma_s_g', nuc_zz, T)
    key_gh = ('sigma_s_gh', nuc_zz, T)

    # Don't recalculate anything if you don't have to
    if key_g in xs_cache:
        return xs_cache[key_g]

    # This calculation requires the scattering kernel
    if key_gh not in xs_cache:
        xs_cache[key_gh] = sigma_s_gh(nuc, T, E_g, E_n, phi_n)

    # Sum over all h
    sig_s_g = xs_cache[key_gh].sum(axis=1)

    # Put this value back into the cache, with the appropriate label
    xs_cache[key_g] = sig_s_g

    return sig_s_g
Example #26
0
def parse_simple_xs(build_dir=""):
    """Builds and returns a dictionary from cross-section types to nuclides."""
    build_dir = os.path.join(build_dir, "KAERI")

    # Grab and parse elemental summary files.
    all_nuclides = set()
    for element in nucname.name_zz.keys():
        htmlfile = element + ".html"
        all_nuclides = all_nuclides | parse_for_all_isotopes(os.path.join(build_dir, htmlfile))

    all_nuclides = sorted([nucname.zzaaam(nuc) for nuc in all_nuclides])

    energy_tables = {eng: np.zeros(len(all_nuclides), dtype=simple_xs_dtype) for eng in simple_xs_energy.keys()}

    # Loop through species
    for i, nuc_zz in enumerate(all_nuclides):
        nuc_name = nucname.name(nuc_zz)
        filename = os.path.join(build_dir, nuc_name + "_2.html")

        # Loop through all energy types
        for eng in simple_xs_energy:
            energy_tables[eng]["nuc_name"][i] = nuc_name
            energy_tables[eng]["nuc_zz"][i] = nuc_zz

            # Loop trhough reactions
            for chan in simple_xs_channels:
                energy_tables[eng][chan][i] = get_xs_from_file(filename, eng, chan)

    for eng in simple_xs_energy:
        # Store only non-trivial entries
        mask = (
            energy_tables[eng][simple_xs_channels.keys()]
            != np.zeros(1, dtype=simple_xs_dtype)[simple_xs_channels.keys()]
        )
        energy_tables[eng] = energy_tables[eng][mask]

        # Calculate some xs
        energy_tables[eng]["sigma_s"] = energy_tables[eng]["sigma_e"] + energy_tables[eng]["sigma_i"]

        energy_tables[eng]["sigma_a"] = (
            energy_tables[eng]["sigma_gamma"]
            + energy_tables[eng]["sigma_f"]
            + energy_tables[eng]["sigma_alpha"]
            + energy_tables[eng]["sigma_proton"]
            + energy_tables[eng]["sigma_deut"]
            + energy_tables[eng]["sigma_trit"]
            + energy_tables[eng]["sigma_2n"]
            + energy_tables[eng]["sigma_3n"]
            + energy_tables[eng]["sigma_4n"]
        )
    return energy_tables
Example #27
0
def grab_photon_fp_info(raw_data):
    """Grabs the photon fission product info.

    Parameters
    ----------
    raw_data : str
        string of the cinder.dat data file.

    Returns
    -------
    info_table : array 
        Structured array with the form "(index, nuc_name, nuc_zz, type, mass)". 
    """
    # Get group sizes
    N_n, N_g = get_fp_sizes(raw_data)

    # Grab the part of the file that is a neutron fission product yield info
    m_info = re.search(gfp_info_pattern, raw_data, re.DOTALL)
    gfp_info_raw = m_info.group(0)

    # Grab the index, nuctope, and type
    iits = re.findall(iit_pattern, gfp_info_raw)

    # Grab the masses 
    masses = re.findall(mass_pattern, gfp_info_raw)

    # Make sure data is the right size
    assert N_g == len(iits) 
    assert N_g == len(masses)

    # Make info table rows 
    info_table = []
    for m in range(N_g):
        iit = iits[m]
        index = int(iit[0])

        nuc_zz = nucname.zzaaam(iit[1])
        # Correct for metastable flag
        if 0 != nuc_zz%10:
            nuc_zz = nuc_zz + 2000

        nuc_name = nucname.name(nuc_zz)
        type = fp_type_flag[iit[2]]
        mass = float(masses[m])

        info_row = (index, nuc_name, nuc_zz, type, mass)
        info_table.append(info_row)

    info_table = np.array(info_table, dtype=fp_info_dtype)

    return info_table
Example #28
0
 def write(self, libs, dirname):
     if not os.path.isdir(dirname):
         os.makedirs(dirname)
     rownames = ["TIME", "NEUT_PROD", "NEUT_DEST", "BUd"]
     for mat, matlib in libs.items():
         if isinstance(mat, int):
             fname = str(nucname.zzaaam(mat))
         else:
             fname = mat
         lines = [row + "   " + "   ".join(map(str, matlib[row]))
                  for row in rownames]
         nucs = matlib["tracked_nucs"]
         lines.extend(sorted([n + "   " + "   ".
                              join(["{:.4g}".format(f) for f in nucs[n]])
                              for n in nucs]))
         with open(os.path.join(dirname, fname + ".txt"), "w") as f:
             f.write("\n".join(lines))
     track_actinides = [n for n in nucs if nucname.znum(n) in nucname.act]
     with open(os.path.join(dirname, "manifest.txt"), "w") as f:
         f.write("\n".join([str(nucname.zzaaam(act)) for act in track_actinides]))
         f.write("\n")
     with open(os.path.join(dirname, "params.txt"), "w") as f:
         f.write("ENRICHMENT {}\n".format(self.rc.enrichment))
         f.write("BATCHES {}\n".format(self.rc.batches))
         f.write("PNL {}\n".format(self.rc.pnl))
         f.write("BURNUP {}\n".format(sum(libs["fuel"]["BUd"])))
         f.write("FLUX {:.0E}\n".format(np.mean(libs["fuel"]["phi_tot"][1:])))
     with open(os.path.join(dirname, "structural.txt"), "w") as f:
         clad_linear_density = pi * self.rc.clad_density * \
             (self.rc.clad_cell_radius ** 2 - self.rc.void_cell_radius ** 2)
         fuel_linear_density = pi * self.rc.fuel_density * \
             self.rc.fuel_cell_radius ** 2
         clad_frac = float(clad_linear_density / fuel_linear_density)
         cladrows = ["{} {:.8f}".format(nucname.zzaaam(n), f*clad_frac)
                     for n, f in self.rc.clad_material.comp.items()]
         f.write("\n".join(cladrows))
         f.write("\n")
     shutil.copyfile("TAPE9.INP", os.path.join(dirname, "TAPE9.INP"))
Example #29
0
def sigma_s(nuc, temp=300.0, group_struct=None, phi_g=None, xs_cache=None):
    """Calculates the neutron scattering cross section for a nuclide. 

    .. math::
        \\sigma_{s, g} = \\sum_{h} \\sigma_{s, g\\to h} 

    Parameters
    ----------
    nuc : int, str, Material, or dict-like 
        A nuclide or nuclide-atom fraction mapping.
    temp : float, optional
        Temperature [K] of material, defaults to 300.0.
    group_struct : array-like of floats, optional
        Energy group structure E_g [MeV] from highest-to-lowest energy, length G+1,
        defaults to xs_cache['E_g'].
    phi_g : array-like of floats, optional
        Group fluxes [n/cm^2/s] matching group_struct, length G, defaults to 
        xs_cache['phi_g'].
    xs_cache : XSCache, optional
        Cross section cache to use, defaults to pyne.xs.cache.xs_cache. 

    Returns
    -------
    sig_s_g : ndarray 
        The scattering cross section, length G.

    """
    xs_cache = cache.xs_cache if xs_cache is None else xs_cache
    _prep_cache(xs_cache, group_struct, phi_g)
    if isinstance(nuc,
                  collections.Iterable) and not isinstance(nuc, basestring):
        return _atom_weight_channel(sigma_s, nuc, temp=temp, xs_cache=xs_cache)
    nuc = nucname.zzaaam(nuc)
    key_g = (nuc, 's_g', temp)
    key_gh = (nuc, 's_gh', temp)

    # Don't recalculate anything if you don't have to
    if key_g in xs_cache:
        return xs_cache[key_g]

    # This calculation requires the scattering kernel
    if key_gh not in xs_cache:
        xs_cache[key_gh] = sigma_s_gh(nuc, temp, group_struct, phi_g, xs_cache)

    # Sum over all h
    sig_s_g = xs_cache[key_gh].sum(axis=1)

    # Put this value back into the cache, with the appropriate label
    xs_cache[key_g] = sig_s_g
    return sig_s_g
Example #30
0
def parse_simple_xs(build_dir=""):
    """Builds and returns a dictionary from cross-section types to nuclides."""
    build_dir = os.path.join(build_dir, 'KAERI')

    # Grab and parse elemental summary files.
    all_nuclides = set()
    for element in nucname.name_zz.keys():
        htmlfile = element + '.html'
        all_nuclides = all_nuclides | parse_for_all_isotopes(
            os.path.join(build_dir, htmlfile))

    all_nuclides = sorted([nucname.zzaaam(nuc) for nuc in all_nuclides])

    energy_tables = dict([(eng, np.zeros(len(all_nuclides), dtype=simple_xs_dtype)) \
                          for eng in simple_xs_energy.keys()])

    # Loop through species
    for i, nuc in enumerate(all_nuclides):
        nuc_name = nucname.name(nuc)
        filename = os.path.join(build_dir, nuc_name + '_2.html')

        # Loop through all energy types
        for eng in simple_xs_energy:
            energy_tables[eng]['nuc'][i] = nuc

            # Loop trhough reactions
            for chan in simple_xs_channels:
                energy_tables[eng][chan][i] = get_xs_from_file(
                    filename, eng, chan)

    for eng in simple_xs_energy:
        # Store only non-trivial entries
        mask = (energy_tables[eng][simple_xs_channels.keys()] != np.zeros(
            1, dtype=simple_xs_dtype)[simple_xs_channels.keys()])
        energy_tables[eng] = energy_tables[eng][mask]

        # Calculate some xs
        energy_tables[eng]['sigma_s'] = energy_tables[eng][
            'sigma_e'] + energy_tables[eng]['sigma_i']

        energy_tables[eng]['sigma_a'] = energy_tables[eng]['sigma_gamma'] + \
                                        energy_tables[eng]['sigma_f'] + \
                                        energy_tables[eng]['sigma_alpha'] + \
                                        energy_tables[eng]['sigma_proton'] + \
                                        energy_tables[eng]['sigma_deut'] + \
                                        energy_tables[eng]['sigma_trit'] + \
                                        energy_tables[eng]['sigma_2n'] + \
                                        energy_tables[eng]['sigma_3n'] + \
                                        energy_tables[eng]['sigma_4n']
    return energy_tables
Example #31
0
def test_chi():
    if not hasattr(rx_h5.root, 'chi'):
        raise nose.SkipTest

    for nuc in nucs:    
        nuc_zz = nucname.zzaaam(nuc)

        chi_arr, chi = read_array(rx_h5.root.chi, nuc)
        sig_f_arr, sig_f = read_array(rx_h5.root.sigma_f, nuc)

        if 86 <= (nuc_zz/10000):
            yield check_array_almost_eq, 1.0, chi.sum(axis=1), ['1.0', 'sum(' + chi_arr._v_pathname + ')']
        else:
            yield check_eq, 0.0, chi, ['0.0', chi_arr._v_pathname]
Example #32
0
def grab_photon_fp_info(raw_data):
    """Grabs the photon fission product info.

    Parameters
    ----------
    raw_data : str
        string of the cinder.dat data file.

    Returns
    -------
    info_table : array 
        Structured array with the form "(index, nuc, type, mass)". 
    """
    # Get group sizes
    N_n, N_g = get_fp_sizes(raw_data)

    # Grab the part of the file that is a neutron fission product yield info
    m_info = re.search(gfp_info_pattern, raw_data, re.DOTALL)
    gfp_info_raw = m_info.group(0)

    # Grab the index, nuctope, and type
    iits = re.findall(iit_pattern, gfp_info_raw)

    # Grab the masses
    masses = re.findall(mass_pattern, gfp_info_raw)

    # Make sure data is the right size
    assert N_g == len(iits)
    assert N_g == len(masses)

    # Make info table rows
    info_table = []
    for m in range(N_g):
        iit = iits[m]
        index = int(iit[0])

        nuc = nucname.zzaaam(iit[1])
        # Correct for metastable flag
        if 0 != nuc % 10:
            nuc = nuc + 2000

        type = fp_type_flag[iit[2]]
        mass = float(masses[m])

        info_row = (index, nuc, type, mass)
        info_table.append(info_row)

    info_table = np.array(info_table, dtype=fp_info_dtype)

    return info_table
Example #33
0
def sigma_t(nuc, temp=300.0, group_struct=None, phi_g=None, xs_cache=None):
    """Calculates the total neutron cross section for a nuclide. 

    .. math::
        \\sigma_{t, g} = \\sigma_{a, g} + \\sigma_{s, g}

    Parameters
    ----------
    nuc : int, str, Material, or dict-like 
        A nuclide or nuclide-atom fraction mapping.
    temp : float, optional
        Temperature [K] of material, defaults to 300.0.
    group_struct : array-like of floats, optional
        Energy group structure E_g [MeV] from highest-to-lowest energy, length G+1,
        defaults to xs_cache['E_g'].
    phi_g : array-like of floats, optional
        Group fluxes [n/cm^2/s] matching group_struct, length G, defaults to 
        xs_cache['phi_g'].
    xs_cache : XSCache, optional
        Cross section cache to use, defaults to pyne.xs.cache.xs_cache. 

    Returns
    -------
    sig_t_g : ndarray 
        The total cross section, length G.

    """
    xs_cache = cache.xs_cache if xs_cache is None else xs_cache
    _prep_cache(xs_cache, group_struct, phi_g)
    if isinstance(nuc,
                  collections.Iterable) and not isinstance(nuc, basestring):
        return _atom_weight_channel(sigma_t, nuc, temp=temp, xs_cache=xs_cache)
    nuc = nucname.zzaaam(nuc)
    key_a = (nuc, 'a', temp)
    key_s = (nuc, 's', temp)
    key_t = (nuc, 't', temp)

    # Don't recalculate anything if you don't have to
    if key_t in xs_cache:
        return xs_cache[key_t]

    # This calculation requires the abosorption cross-section
    if key_a not in xs_cache:
        xs_cache[key_a] = sigma_a(nuc, temp, group_struct, phi_g, xs_cache)
    if key_s not in xs_cache:
        xs_cache[key_s] = sigma_s(nuc, temp, group_struct, phi_g, xs_cache)
    sig_t_g = xs_cache[key_a] + xs_cache[key_s]
    xs_cache[key_t] = sig_t_g
    return sig_t_g
Example #34
0
def sigma_s(nuc, temp=300.0, group_struct=None, phi_g=None, xs_cache=None):
    """Calculates the neutron scattering cross section for a nuclide. 

    .. math::
        \\sigma_{s, g} = \\sum_{h} \\sigma_{s, g\\to h} 

    Parameters
    ----------
    nuc : int, str, Material, or dict-like 
        A nuclide or nuclide-atom fraction mapping.
    temp : float, optional
        Temperature [K] of material, defaults to 300.0.
    group_struct : array-like of floats, optional
        Energy group structure E_g [MeV] from highest-to-lowest energy, length G+1,
        defaults to xs_cache['E_g'].
    phi_g : array-like of floats, optional
        Group fluxes [n/cm^2/s] matching group_struct, length G, defaults to 
        xs_cache['phi_g'].
    xs_cache : XSCache, optional
        Cross section cache to use, defaults to pyne.xs.cache.xs_cache. 

    Returns
    -------
    sig_s_g : ndarray 
        The scattering cross section, length G.

    """
    xs_cache = cache.xs_cache if xs_cache is None else xs_cache
    _prep_cache(xs_cache, group_struct, phi_g)
    if isinstance(nuc, collections.Iterable) and not isinstance(nuc, basestring):
        return _atom_weight_channel(sigma_s, nuc, temp=temp, xs_cache=xs_cache)
    nuc = nucname.zzaaam(nuc)
    key_g = (nuc, "s_g", temp)
    key_gh = (nuc, "s_gh", temp)

    # Don't recalculate anything if you don't have to
    if key_g in xs_cache:
        return xs_cache[key_g]

    # This calculation requires the scattering kernel
    if key_gh not in xs_cache:
        xs_cache[key_gh] = sigma_s_gh(nuc, temp, group_struct, phi_g, xs_cache)

    # Sum over all h
    sig_s_g = xs_cache[key_gh].sum(axis=1)

    # Put this value back into the cache, with the appropriate label
    xs_cache[key_g] = sig_s_g
    return sig_s_g
Example #35
0
def sigma_t(nuc, temp=300.0, group_struct=None, phi_g=None, xs_cache=None):
    """Calculates the total neutron cross section for a nuclide. 

    .. math::
        \\sigma_{t, g} = \\sigma_{a, g} + \\sigma_{s, g}

    Parameters
    ----------
    nuc : int, str, Material, or dict-like 
        A nuclide or nuclide-atom fraction mapping.
    temp : float, optional
        Temperature [K] of material, defaults to 300.0.
    group_struct : array-like of floats, optional
        Energy group structure E_g [MeV] from highest-to-lowest energy, length G+1,
        defaults to xs_cache['E_g'].
    phi_g : array-like of floats, optional
        Group fluxes [n/cm^2/s] matching group_struct, length G, defaults to 
        xs_cache['phi_g'].
    xs_cache : XSCache, optional
        Cross section cache to use, defaults to pyne.xs.cache.xs_cache. 

    Returns
    -------
    sig_t_g : ndarray 
        The total cross section, length G.

    """
    xs_cache = cache.xs_cache if xs_cache is None else xs_cache
    _prep_cache(xs_cache, group_struct, phi_g)
    if isinstance(nuc, collections.Iterable) and not isinstance(nuc, basestring):
        return _atom_weight_channel(sigma_t, nuc, temp=temp, xs_cache=xs_cache)
    nuc = nucname.zzaaam(nuc)
    key_a = (nuc, "a", temp)
    key_s = (nuc, "s", temp)
    key_t = (nuc, "t", temp)

    # Don't recalculate anything if you don't have to
    if key_t in xs_cache:
        return xs_cache[key_t]

    # This calculation requires the abosorption cross-section
    if key_a not in xs_cache:
        xs_cache[key_a] = sigma_a(nuc, temp, group_struct, phi_g, xs_cache)
    if key_s not in xs_cache:
        xs_cache[key_s] = sigma_s(nuc, temp, group_struct, phi_g, xs_cache)
    sig_t_g = xs_cache[key_a] + xs_cache[key_s]
    xs_cache[key_t] = sig_t_g
    return sig_t_g
Example #36
0
    def write(self, libs, dirname):
        """Write out libraries to a directory.

        Parameters
        ----------
        libs : dict
            The reactor libraries gleaned from buk.
        dirname : str
            The output directory.
        """
        if not os.path.isdir(dirname):
            os.makedirs(dirname)
        rownames = ["TIME", "phi_tot", "NEUT_PROD", "NEUT_DEST", "BUd"]
        for mat, matlib in libs.items():
            if isinstance(mat, int):
                fname = str(nucname.zzaaam(mat))
            elif mat == 'fuel':
                fname = mat
            else:
                continue
            trans_matrix = {}
            if os.path.isdir(os.path.join(dirname, fname + ".txt")):
                libs, trans_matrix = self.update(libs, dirname, fname)
            else:
                i = 0 
                while i < len(matlib['material']):
                    for temp_nuc in matlib['material'][i].comp:
                        nuc_name = str(nucname.name(temp_nuc))
                        try:
                            trans_matrix[nuc_name].append(matlib['material'][i].comp[temp_nuc]*1000)
                        except KeyError:
                            if matlib['material'][i].comp[temp_nuc] > self.rc.track_nuc_threshold:
                                zero_array = [0.]*i
                                trans_matrix[nuc_name] = zero_array
                                trans_matrix[nuc_name].append(matlib['material'][i].comp[temp_nuc]*1000)
                    i+=1
            lines = [row + "   " + "   ".join(map(str, matlib[row]))
                for row in rownames]
            lines.extend(sorted([n + "   " + "   ".
                                 join(["{:.4g}".format(f) for f in trans_matrix[n]])
                                 for n in trans_matrix]))
            with open(os.path.join(dirname, fname + ".txt"), "w") as f:
                f.write("\n".join(lines))
            nucs = matlib["tracked_nucs"]
        if not os.path.isfile(os.path.join(dirname, "manifest.txt")):
            self.write_metadata(nucs, libs, dirname)
Example #37
0
def parse_eaf_xs(build_file):
    """Create numpy array by parsing EAF data
    using regular expressions

    Parameters
    ----------
    build_file : str
        Path where EAF data is stored.
    
    Returns
    -------
    eaf_array : numpy array
        Numpy array with a row for each isotope+reaction combination
        found in the EAF data.

    """
    
    with open(build_file, 'r') as f:
        raw_data = f.read()

    eaf_data = list()
    eaf_pattern = eaf_info_pattern + eaf_bin_pattern 

    # Iterate over all iso/rx combinations in file
    for m in re.finditer(eaf_pattern, raw_data, re.DOTALL):
        md = m.groupdict()

        xs_list = [float(x) for x in md['xs'].split()]
        xs_list += (175-len(xs_list))*[0.0]

        # Store information in new row of array.
        eafrow = (
                  nucname.zzaaam(md['iso']),
                  md['rxnum'],
                  md['rxstr'],
                  md['daugh'],
                  xs_list
                  )
        
        eaf_data.append(eafrow)

    eaf_array = np.array(eaf_data, dtype=eaf_dtype)

    print "Read in {0} sets of EAF data.".format(len(eaf_array))

    return eaf_array
Example #38
0
def parse_simple_xs(build_dir=""):
    """Builds and returns a dictionary from cross-section types to nuclides."""
    build_dir = os.path.join(build_dir, 'KAERI')

    # Grab and parse elemental summary files.
    all_nuclides = set()
    for element in nucname.name_zz.keys():
        htmlfile = element + '.html'
        all_nuclides = all_nuclides | parse_for_all_isotopes(os.path.join(build_dir, htmlfile))

    all_nuclides = sorted([nucname.zzaaam(nuc) for nuc in all_nuclides])

    energy_tables = dict([(eng, np.zeros(len(all_nuclides), dtype=simple_xs_dtype)) \
                          for eng in simple_xs_energy.keys()])

    # Loop through species
    for i, nuc in enumerate(all_nuclides):
        nuc_name = nucname.name(nuc)
        filename = os.path.join(build_dir, nuc_name + '_2.html')

        # Loop through all energy types
        for eng in simple_xs_energy:
            energy_tables[eng]['nuc'][i] = nuc

            # Loop trhough reactions
            for chan in simple_xs_channels:
                energy_tables[eng][chan][i] = get_xs_from_file(filename, eng, chan)

    for eng in simple_xs_energy:
        # Store only non-trivial entries
        mask = (energy_tables[eng][simple_xs_channels.keys()] != np.zeros(1, dtype=simple_xs_dtype)[simple_xs_channels.keys()])
        energy_tables[eng] = energy_tables[eng][mask]

        # Calculate some xs
        energy_tables[eng]['sigma_s'] = energy_tables[eng]['sigma_e'] + energy_tables[eng]['sigma_i']

        energy_tables[eng]['sigma_a'] = energy_tables[eng]['sigma_gamma'] + \
                                        energy_tables[eng]['sigma_f'] + \
                                        energy_tables[eng]['sigma_alpha'] + \
                                        energy_tables[eng]['sigma_proton'] + \
                                        energy_tables[eng]['sigma_deut'] + \
                                        energy_tables[eng]['sigma_trit'] + \
                                        energy_tables[eng]['sigma_2n'] + \
                                        energy_tables[eng]['sigma_3n'] + \
                                        energy_tables[eng]['sigma_4n']
    return energy_tables
Example #39
0
    def get_nuc_name(self, nuc_code):
        """Returns nuclide name in human-readable notation: chemical symbol
        (one or two characters), dash, and the atomic weight. Lastly, if the
        nuclide is in metastable state, the letter `m` is concatenated with
        number of excited state. For example, `Am-242m1`.

        Parameters
        ----------
        nuc_code : str
            Name of nuclide in Serpent2 form. For instance, `Am-242m`.

        Returns
        -------
        nuc_name : str
            Name of nuclide in human-readable notation (`Am-242m1`).
        nuc_zzaaam : str
            Name of nuclide in `zzaaam` form (`952421`).

        """

        if '.' in str(nuc_code):
            nuc_code = pyname.zzzaaa_to_id(int(nuc_code.split('.')[0]))
            zz = pyname.znum(nuc_code)
            aa = pyname.anum(nuc_code)
            aa_str = str(aa)
            # at_mass = pydata.atomic_mass(nuc_code_id)
            if aa > 300:
                if zz > 76:
                    aa_str = str(aa - 100) + 'm1'
                    aa = aa - 100
                else:
                    aa_str = str(aa - 200) + 'm1'
                    aa = aa - 200
                nuc_zzaaam = str(zz) + str(aa) + '1'
            elif aa == 0:
                aa_str = 'nat'
            nuc_name = pyname.zz_name[zz] + aa_str
        else:
            meta_flag = pyname.snum(nuc_code)
            if meta_flag:
                nuc_name = pyname.name(nuc_code)[:-1] + 'm' + str(meta_flag)
            else:
                nuc_name = pyname.name(nuc_code)
        nuc_zzaaam = \
            self.convert_nuclide_name_serpent_to_zam(pyname.zzaaam(nuc_code))
        return nuc_name, nuc_zzaaam
Example #40
0
 def _load_reaction(self, nuc, rx, temp=300.0):
     nuc = nucname.zzaaam(nuc)
     if rx not in self._rx_avail:
         return None
     cond = "nuc == {0}".format(nuc)
     sig = 'sigma_' + 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 findParents(energyList, energyUncertainty):
    """Find parent elements of a given intensity peak.

    Args:
        energyList: The energies with an intensity peak in our dataset.
        energyUncertainty: Energy Uncertainties associated with each
            energy (in order) of our dataset.  
    """
    elements = []
    for i in range(len(energyList)):
        for j in data.gamma_parent(energyList[i], energyUncertainty[i]):
            if j > 0:
                try:
                    if nucname.zzaaam(j) % 2 == 0:
                        elements.append(j)
                except:
                    doNothing = 1
                    raise
    return elements
Example #42
0
    def _load_reaction(self, nuc, rx, temp=300.0):
        nuc = nucname.zzaaam(nuc)
        rx = _munge_rx(rx)

        # Set query condition
        if rx == 'f':
            cond = 'nuc == {0}'.format(nuc)
        elif rx in RX_TYPES:
            cond = "(from_nuc == {0}) & (reaction_type == '{1}')".format(nuc, rx)
        else:
            return None

        with tb.openFile(nuc_data, 'r') as f:
            node = f.root.neutron.cinder_xs.fission if rx == 'f' 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)
        elif 0 == len(rows) and (rx == 'a'):
            # in case absorption doesn't exist, we compute it
            fdata = self._load_reaction(nuc, 'f')
            cond = "(from_nuc == {0}) & (reaction_type != 'c')".format(nuc)
            with tb.openFile(nuc_data, 'r') as f:
                node = f.root.neutron.cinder_xs.absorption
                rows = np.array([row['xs'] for row in node.where(cond)])
            if 0 == len(rows) and fdata is None:
                rxdata = None
            else:
                rxdata = rows.sum(axis=0)
                if fdata is not None:
                    rxdata += fdata
        else:
            rxdata = None
        return rxdata
Example #43
0
def sigma_f(nuc, temp=300.0, group_struct=None, phi_g=None, xs_cache=None):
    """Calculates the neutron fission cross section for a nuclide. 

    Parameters
    ----------
    nuc : int, str, Material, or dict-like 
        A nuclide or nuclide-atom fraction mapping.
    temp : float, optional
        Temperature [K] of material, defaults to 300.0.
    group_struct : array-like of floats, optional
        Energy group structure E_g [MeV] from highest-to-lowest energy, length G+1,
        defaults to xs_cache['E_g'].
    phi_g : array-like of floats, optional
        Group fluxes [n/cm^2/s] matching group_struct, length G, defaults to 
        xs_cache['phi_g'].
    xs_cache : XSCache, optional
        Cross section cache to use, defaults to pyne.xs.cache.xs_cache. 

    Returns
    -------
    sigma_f_g : ndarray 
        The fission cross-section, length G.

    Notes
    -----
    This always pulls the fission cross section out of the cache.

    """
    xs_cache = cache.xs_cache if xs_cache is None else xs_cache
    _prep_cache(xs_cache, group_struct, phi_g)
    if isinstance(nuc,
                  collections.Iterable) and not isinstance(nuc, basestring):
        return _atom_weight_channel(sigma_f, nuc, temp=temp, xs_cache=xs_cache)
    nuc = nucname.zzaaam(nuc)
    key = (nuc, 'f', temp)
    return xs_cache[key]
Example #44
0
def parse_scattering_lengths(build_dir):
    """Converts to scattering lenth data to a numpy array."""
    build_filename = os.path.join(build_dir, "scattering_lengths.html")

    # Read in cinder data file
    with open(build_filename, 'r') as f:
        raw_data = f.read()

    sl_data = []

    # Iterate over all isotopes in the table
    for m in re.finditer(scat_len_pattern, raw_data):
        md = m.groupdict()

        slrow = (nucname.zzaaam(md['iso']),
                 nist_num(md['b_coherent']) * (1E-13),
                 nist_num(md['b_incoherent']) * (1E-13),
                 nist_num(md['xs_coherent']), nist_num(md['xs_incoherent']),
                 nist_num(md['xs']))

        sl_data.append(slrow)

    sl_array = np.array(sl_data, dtype=sl_dtype)
    return sl_array
Example #45
0
def make_mg_absorption(nuc_data, build_dir=""):
    """Adds the absorption reaction rate cross sections to the hdf5 library.

    Parameters
    ----------
    nuc_data : str
        Path to nuclide data file.
    build_dir : str
        Directory with cinder.dat file.
    """
    # Open the HDF5 File
    db = tb.openFile(nuc_data, 'a', filters=BASIC_FILTERS)

    # Ensure that the appropriate file structure is present
    _init_cinder(db)

    # Read in cinder data file
    cinder_dat = os.path.join(build_dir, 'cinder.dat')
    with open(cinder_dat, 'r') as f:
        raw_data = f.read()

    # Get group sizes
    nuclides, G_n, G_p, G_g = get_group_sizes(raw_data)

    # Init the neutron absorption table
    absorption_dtype = np.dtype(absorption_dtype_tuple + [('xs', float, G_n)])
    absorption_table = db.createTable(
        '/neutron/cinder_xs/', 'absorption', np.empty(0,
                                                      dtype=absorption_dtype),
        'Neutron absorption reaction cross sections [barns]')
    abrow = absorption_table.row

    # Init to_nuc_pattern
    to_nuc_pattern = to_nuc_base + ("\s+(" + cinder_float + ")") * G_n

    # Iterate through all from nuctopes.
    for m_from in re.finditer(from_nuc_pattern, raw_data, re.DOTALL):
        from_nuc = nucname.zzaaam(m_from.group(1))

        # Check matestable state
        if 1 < from_nuc % 10:
            # Metastable state too high!
            continue

        # Grab the string for this from_nuc in order to get all of the to_nucs
        from_nuc_part = m_from.group(0)

        # Iterate over all to_nucs
        for m_to in re.finditer(to_nuc_pattern, from_nuc_part):
            to_nuc = nucname.zzaaam(m_to.group(1))

            # Check matestable state
            if 1 < to_nuc % 10:
                # Metastable state too high!
                continue

            # Munge reaction type
            rx_type = m_to.group(2)
            rx_type = rx_type.strip()

            # Setup XS array
            xs = np.array(m_to.groups()[-1:1:-1], dtype=float)
            assert xs.shape == (G_n, )

            # Write this row to the absorption table
            abrow['from_nuc'] = from_nuc
            abrow['to_nuc'] = to_nuc
            abrow['reaction_type'] = rx_type
            abrow['xs'] = xs

            abrow.append()

        # Flush this from nuc
        absorption_table.flush()

    # Close the hdf5 file
    db.close()
Example #46
0
def parse_tape6(tape6="TAPE6.OUT"):
    """Parses an ORIGEN 2.2 TAPE6.OUT file. 

    Parameters
    ----------
    tape6 : str or file-like object
        Path or file to read the tape6 file from.

    Returns
    -------
    results : dict 
        Dictionary of parsed values.

    Warnings
    --------
    This method currently only functions to extract neutronic data from TAPE6
    files.  It does not yet parse out photonic data.  If you would like to see
    this feature added, please contact the developers.

    Notes
    -----
    The results dictionary that is returned is highly structured and generally
    matches the layout of the TAPE6 file.  Data is stored as 1d numpy float arrays
    which (if the TAPE6 is well-formed) will all be of the same length and match
    the time vector.  The possible layout of results is as follows::

      |- 'time_sec': time per index in [seconds]
      |- 'flux': neutron flux at this time [n/cm^2/s]
      |- 'specific_power_MW': recator specific power at this time [MW]
      |- 'burnup_MWD': reactor burnup since last time step [MWd/input mass [g] from TAPE4]
      |- 'k_inf': infinite multiplication factor [unitless]
      |- 'neutron_production_rate': Total reactor neutron production rate [n/s]
      |- 'neutron_destruction_rate: Total reactor neutron destruction rate [n/s]
      |- 'total_burnup': Cummulative burnup over all time [MWd/input mass [g] from TAPE4]
      |- 'average_flux': average neutron flux over preceeding time interval [n/cm^2/s]
      |- 'average_specific_power: recator specific power over preceeding time interval [MW]
      |- 'materials': list of Materials of same length as 'time_sec', only present if 
      |               'table_3' or 'table_5' exist and have 'nuclide' output.
      |- 'alpha_neutron_source': dict
      |                          |- 'title': str
      |                          |- 'units': str
      |                          |- nuclide or element str: (alpha, n) neutron source [n/s] 
      |- 'spont_fiss_neutron_source': dict
      |                          |- 'title': str
      |                          |- 'units': str
      |                          |- nuclide or element str: spontaneous fission neutron source [n/s] 
      |- 'table_{n}': dict
      |               |- 'nuclide': dict
      |               |             |- 'title': str
      |               |             |- 'units': str
      |               |             |- 'activation_products': dict of (nuc-zzaaam, data) pairs
      |               |             |- 'actinides': dict of (nuc-zzaaam, data) pairs
      |               |             |- 'fission_products': dict of (nuc-zzaaam, data) pairs
      |               |- 'element': dict
      |               |             |- 'title': str
      |               |             |- 'units': str
      |               |             |- 'activation_products': dict of (elem str, data) pairs
      |               |             |- 'actinides': dict of (elem str, data) pairs
      |               |             |- 'fission_products': dict of (elem str, data) pairs
      |               |- 'summary': dict
      |               |             |- 'title': str
      |               |             |- 'units': str
      |               |             |- 'activation_products': dict of (elem or nuc str, data) pairs
      |               |             |- 'actinides': dict of (elem or nuc str, data) pairs
      |               |             |- 'fission_products': dict of (elem or nuc str, data) pairs
 
    """
    # Read the TAPE6 file
    opened_here = False
    if isinstance(tape6, basestring):
        tape6 = open(tape6, 'r')
        opened_here = True

    lines = tape6.readlines()

    if opened_here:
        tape6.close()

    # Prep to parse the file
    results = {}

    # Defaults
    table_key = None
    table_type = None
    table_group = None

    # Read in the file line-by-line
    for i, line in enumerate(lines):
        # Get reactivity and burnup data
        m = _rx_bu_data_line.match(line)
        if m is not None:
            key, data = m.groups()
            new_key = _rx_bu_key_map[key]
            arr_data = np.array(data.split(), dtype=float)
            curr_data = results.get(new_key, [])
            results[new_key] = np.append(curr_data, arr_data)
            continue

        # Get table spcies group
        m = _species_group_line.match(line)
        if m is not None:
            table_group = _group_key_map[m.group(1)]
            continue

        # Get table header info
        m = _table_header_line.match(line) or _table_header_alpha_line.match(
            line)
        if m is not None:
            tnum, ttype, ttitle, tunits = m.groups()

            table_key = "table_{0}".format(tnum)
            if table_key not in results.keys():
                results[table_key] = {}

            table_type = ttype.lower()
            if table_type not in results[table_key]:
                results[table_key][table_type] = {}

            results[table_key][table_type]["title"] = ttitle.strip().lower()
            results[table_key][table_type]["units"] = tunits.strip().lower()
            if table_group not in results[table_key][table_type]:
                results[table_key][table_type][table_group] = {}
            continue

        # Grab nuclide data lines
        m = _nuclide_line.match(line)
        if (m is not None) and (table_key is not None):
            nuc, data = m.groups()
            nuc_name = nuc.replace(' ', '')

            # Don't know WTF element 'SF' is suppossed to be! (Spent fuel, spontaneous fission)
            if nuc_name == 'SF250':
                continue

            nuc_zz = nucname.zzaaam(nuc_name)
            nuc_key = nuc_zz if table_type == 'nuclide' else nuc_name
            nuc_data = np.array(data.split(), dtype=float)

            if table_key.startswith('table_'):
                curr_data = results[table_key][table_type][table_group].get(
                    nuc_key, [])
                results[table_key][table_type][table_group][
                    nuc_key] = np.append(curr_data, nuc_data)
            else:
                curr_data = results[table_key].get(nuc_key, [])
                results[table_key][nuc_key] = np.append(curr_data, nuc_data)
            continue

        # Grab element data line
        m = _element_line.match(line)
        if (m is not None) and (table_key is not None):
            elem, data = m.groups()
            elem = elem.replace(' ', '')

            # Still don't know WTF element 'SF' is suppossed to be! (Spent fuel, spontaneous fission)
            if elem == 'SF':
                continue

            elem_data = np.array(data.split(), dtype=float)

            if table_key.startswith('table_'):
                curr_data = results[table_key][table_type][table_group].get(
                    elem, [])
                results[table_key][table_type][table_group][elem] = np.append(
                    curr_data, elem_data)
            else:
                curr_data = results[table_key].get(elem, [])
                results[table_key][elem] = np.append(curr_data, elem_data)
            continue

        # Grab (alpha, n) and spontaneous fission headers
        m = _alpha_n_header_line.match(line) or _spont_fiss_header_line.match(
            line)
        if m is not None:
            ttitle, tunits = m.groups()

            table_key = _n_source_key_map[ttitle]
            if table_key not in results.keys():
                results[table_key] = {}

            table_type = None
            table_group = None

            results[table_key]["title"] = ttitle.strip().lower()
            results[table_key]["units"] = tunits.strip().lower()
            continue

        # Photon spectra parsing is not yet supported
        m = _photon_spec_header_line.match(line)
        if m is not None:
            table_key = None
            table_type = None
            table_group = None

    # Done with parsing, try to convert to material
    tbl = None
    if ('table_5' in results) and ('nuclide' in results['table_5']):
        tbl = 'table_5'
        mat_gen = Material
    elif ('table_3' in results) and ('nuclide' in results['table_3']):
        tbl = 'table_3'
        mat_gen = from_atom_frac

    if tbl is not None:
        T = len(results['time_sec'])
        mats = [Material() for t in range(T)]

        for grp in _group_key_map.values():
            if grp in results[tbl]['nuclide']:
                mats = [m + mat_gen(dict([(nuc, arr[i]) for nuc, arr in \
                                            results[tbl]['nuclide'][grp].items()])) \
                                            for i, m in enumerate(mats)]

        results['materials'] = mats

    return results
Example #47
0
def test_zzaaam():
    assert_equal(nucname.zzaaam(20040), 20040)

    assert_equal(nucname.zzaaam("he4"), 20040)
    assert_equal(nucname.zzaaam("Cm-244"), 962440)
    assert_equal(nucname.zzaaam("PU239"), 942390)
    assert_equal(nucname.zzaaam("AM242M"), 952421)

    assert_equal(nucname.zzaaam(2004), 20040)
    assert_equal(nucname.zzaaam(95642), 952420)
    assert_equal(nucname.zzaaam(95242), 952421)
    assert_equal(nucname.zzaaam(92636), 922361)
    assert_equal(nucname.zzaaam(95942), 952424)

    assert_equal(nucname.zzaaam("Am-242m"), 952421)

    assert_equal(nucname.zzaaam("he"), 20000)
    assert_equal(nucname.zzaaam("U"), 920000)
    assert_equal(nucname.zzaaam("Np"), 930000)

    assert_equal(nucname.zzaaam("4he"), 20040)
    assert_equal(nucname.zzaaam("244CM"), 962440)
    assert_equal(nucname.zzaaam("239Pu"), 942390)
    assert_equal(nucname.zzaaam("242AM"), 952420)

    assert_equal(nucname.zzaaam(40020), 20040)
    assert_equal(nucname.zzaaam(2440961), 962441)
    assert_equal(nucname.zzaaam(2390940), 942390)
    assert_equal(nucname.zzaaam(2420950), 952420)
core_adensity_before = np.array(f['core adensity before reproc'])
keff_boc = np.array(f['keff_BOC'])
keff_eoc = np.array(f['keff_EOC'])
tank_adensity = np.array(f['tank adensity'])
noble_adensity = np.array([])
iso_codes = np.array(f['iso_codes'])
iso_zai = []
iso_names = []
for code in iso_codes:
    code = code.decode()
    if '.09c' in code:
        code = code.replace('.09c', '')
        code = nucname.zzzaaa_to_id(int(code))
    else:
        code = nucname.zzaaam_to_id(int(code))
    iso_zai.append(nucname.zzaaam(code))
    iso_names.append(nucname.name(code))
iso_zai = np.array(iso_zai)
iso_names = np.array(iso_names)

shape = core_adensity_after.shape


def adens_to_mass(fuel_vol, array, iso_names):
    shape = array.shape
    mass_array = np.zeros(shape)
    for num, row in enumerate(array):
        mat_dict = {}
        mass_comp = np.zeros(len(row))
        for indx, val in enumerate(row):
            mat_dict[iso_names[indx]] = val
Example #49
0
def chi(nuc,
        temp=300.0,
        group_struct=None,
        phi_g=None,
        xs_cache=None,
        eres=101):
    """Calculates the neutron fission energy spectrum for a nuclide.

    Parameters
    ----------
    nuc : int, str, Material, or dict-like 
        A nuclide or nuclide-atom fraction mapping.
    temp : float, optional
        Temperature [K] of material, defaults to 300.0.
    group_struct : array-like of floats, optional
        Energy group structure E_g [MeV] from highest-to-lowest energy, length G+1,
        defaults to xs_cache['E_g'].
    phi_g : array-like of floats, optional
        Group fluxes [n/cm^2/s] matching group_struct, length G, defaults to 
        xs_cache['phi_g'].
    xs_cache : XSCache, optional
        Cross section cache to use, defaults to pyne.xs.cache.xs_cache. 
    eres : int, optional
        Number of energy-points to integrate over per group.

    Returns
    -------
    chi_g : ndarray 
        The fission energy spectrum, length G.

    See Also
    --------
    pyne.xs.models.chi : used under the covers by this function.

    """
    xs_cache = cache.xs_cache if xs_cache is None else xs_cache
    _prep_cache(xs_cache, group_struct, phi_g)
    if isinstance(nuc,
                  collections.Iterable) and not isinstance(nuc, basestring):
        return _atom_weight_channel(chi,
                                    nuc,
                                    temp=temp,
                                    xs_cache=xs_cache,
                                    eres=eres)
    nuc = nucname.zzaaam(nuc)
    key = (nuc, 'chi', temp)

    # Don't recalculate anything if you don't have to
    if key in xs_cache:
        return xs_cache[key]

    # Get the the set of nuclides we know we need chi for.
    if 'fissionable_nucs' not in xs_cache:
        with tb.openFile(pyne.nuc_data, 'r') as f:
            if '/neutron/cinder_xs/fission' in f:
                fn = set(f.root.neutron.cinder_xs.fission.cols.nuc)
            else:
                fn = set()
        xs_cache['fissionable_nucs'] = fn
    fissionable_nucs = xs_cache['fissionable_nucs']
    if (nuc not in fissionable_nucs) and (86 <= nuc / 10000):
        fissionable_nucs.add(nuc)

    # Perform the group collapse on a continuous chi
    E_g = xs_cache['E_g']
    G = len(E_g) - 1
    chi_g = np.zeros(G, dtype='f8')
    if (nuc in fissionable_nucs):
        for g in range(G):
            E_space = np.logspace(np.log10(E_g[g]), np.log10(E_g[g + 1]), eres)
            dnumer = pyne.xs.models.chi(E_space)
            numer = scipy.integrate.trapz(dnumer, E_space)
            denom = (E_g[g + 1] - E_g[g])
            chi_g[g] = (numer / denom)
        # renormalize chi
        chi_g = chi_g / chi_g.sum()
    # Put this value back into the cache, with the appropriate label
    xs_cache[key] = chi_g
    return chi_g
Example #50
0
def metastable_ratio(nuc,
                     rx,
                     temp=300.0,
                     group_struct=None,
                     phi_g=None,
                     xs_cache=None):
    """Calculates the ratio between a reaction that leaves the nuclide in a 
    metastable state and the equivalent reaction that leaves the nuclide in 
    the ground state.  This allows the calculation of metastable cross sections 
    via sigma_ms = ratio * sigma_ground. 

    Parameters
    ----------
    nuc : int, str, Material, or dict-like 
        A nuclide or nuclide-atom fraction mapping.
    rx : str
        Reaction key. ('gamma', 'alpha', 'p', etc.)
    temp : float, optional
        Temperature [K] of material, defaults to 300.0.
    group_struct : array-like of floats, optional
        Energy group structure E_g [MeV] from highest-to-lowest energy, length G+1,
        defaults to xs_cache['E_g'].
    phi_g : array-like of floats, optional
        Group fluxes [n/cm^2/s] matching group_struct, length G, defaults to 
        xs_cache['phi_g'].
    xs_cache : XSCache, optional
        Cross section cache to use, defaults to pyne.xs.cache.xs_cache. 

    Returns
    -------
    ratio_rx_g : ndarray
        An array of the ratio of the metastable cross section for a reaction 
        to the ground state reaction.

    Notes
    -----
    This always pulls the absorption reaction cross section out of the cache.

    See Also
    --------
    pyne.xs.data_source.RX_TYPES
    pyne.xs.data_source.RX_TYPES_MAP 

    """
    if isinstance(nuc, int) or isinstance(nuc, basestring):
        xs_cache = cache.xs_cache if xs_cache is None else xs_cache
        _prep_cache(xs_cache, group_struct, phi_g)
        nuc = nucname.zzaaam(nuc)
        key = (nuc, rx + '_x_ratio', temp)
        if key in xs_cache:
            return xs_cache[key]

    # Get the cross-sections
    sigma_rx = sigma_a_reaction(nuc, rx, temp, group_struct, phi_g, xs_cache)
    sigma_rx_x = sigma_a_reaction(nuc, rx + '_x', temp, group_struct, phi_g,
                                  xs_cache)

    # Get the ratio
    ratio_rx_g = sigma_rx_x / sigma_rx
    ratio_rx_g[ratio_rx_g < 0.0] = 0.0
    ratio_rx_g[ratio_rx_g == np.inf] = 0.0
    ratio_rx_g[np.isnan(ratio_rx_g)] = 0.0

    if isinstance(nuc, int):
        xs_cache[key] = ratio_rx_g
    return ratio_rx_g
Example #51
0
def make_mg_fission(nuc_data, build_dir=""):
    """Adds the fission reaction rate cross sections to the hdf5 library.

    Parameters
    ----------
    nuc_data : str
        Path to nuclide data file.
    build_dir : str
        Directory with cinder.dat file.
    """
    # Open the HDF5 File
    db = tb.openFile(nuc_data, 'a', filters=BASIC_FILTERS)

    # Ensure that the appropriate file structure is present
    _init_cinder(db)

    # Read in cinder data file
    cinder_dat = os.path.join(build_dir, 'cinder.dat')
    with open(cinder_dat, 'r') as f:
        raw_data = f.read()

    # Get group sizes
    nuclides, G_n, G_p, G_g = get_group_sizes(raw_data)

    # Init the neutron absorption table
    fission_dtype = np.dtype(fission_dtype_tuple + [('xs', float, G_n)])
    fission_table = db.createTable(
        '/neutron/cinder_xs/', 'fission', np.empty(0, dtype=fission_dtype),
        'Neutron fission reaction cross sections [barns]')
    frow = fission_table.row

    # Init to_nuc_pattern
    fission_pattern = fission_base + ("\s+(" + cinder_float + ")") * G_n

    # Iterate through all from nuctopes.
    for m_from in re.finditer(from_nuc_pattern, raw_data, re.DOTALL):
        from_nuc = nucname.zzaaam(m_from.group(1))

        # Check matestable state
        if 1 < from_nuc % 10:
            # Metastable state too high!
            continue

        # Grab the string for this from_nuc in order to get all of the to_nucs
        from_nuc_part = m_from.group(0)

        # Grab the fission part
        m_fission = re.search(fission_pattern, from_nuc_part)
        if m_fission is None:
            continue

        # Grab yield indexes
        yield_t = int(m_fission.group(1))
        yield_f = int(m_fission.group(2))
        yield_h = int(m_fission.group(3))

        # Grab XS array
        xs = np.array(m_fission.groups()[-1:2:-1], dtype=float)
        assert xs.shape == (G_n, )

        # Write fission table row
        frow['nuc'] = from_nuc

        frow['thermal_yield'] = yield_t
        frow['fast_yield'] = yield_f
        frow['high_energy_yield'] = yield_h

        frow['xs'] = xs

        # Write out this row
        frow.append()
        fission_table.flush()

    # Close the hdf5 file
    db.close()
Example #52
0
def make_mg_gamma_decay(nuc_data, build_dir=""):
    """Adds the gamma decay spectrum information to the hdf5 library.

    Parameters
    ----------
    nuc_data : str
        Path to nuclide data file.
    build_dir : str
        Directory with cinder.dat file.
    """
    # Open the HDF5 File
    db = tb.openFile(nuc_data, 'a', filters=BASIC_FILTERS)

    # Ensure that the appropriate file structure is present
    _init_cinder(db)

    # Read in cinder data file
    cinder_dat = os.path.join(build_dir, 'cinder.dat')
    with open(cinder_dat, 'r') as f:
        raw_data = f.read()

    # Get group sizes
    nuclides, G_n, G_p, G_g = get_group_sizes(raw_data)

    # Init the gamma absorption table
    gamma_decay_dtype = np.dtype(gamma_decay_dtype_tuple +
                                 [('spectrum', float, G_g)])
    gamma_decay_table = db.createTable('/photon/cinder_source/',
                                       'decay_spectra',
                                       np.empty(0, dtype=gamma_decay_dtype),
                                       'Gamma decay spectrum [MeV]')
    gdrow = gamma_decay_table.row

    # Init to_nuc_pattern
    gamma_decay_pattern = gamma_decay_base + ("\s+(" + cinder_float +
                                              ")") * G_g

    # Iterate through all from nuctopes.
    for m_from in re.finditer(from_nuc_pattern, raw_data, re.DOTALL):
        from_nuc = nucname.zzaaam(m_from.group(1))

        # Check matestable state
        if 1 < from_nuc % 10:
            # Metastable state too high!
            continue

        # Grab the string for this from_nuc in order to get all of the to_nucs
        from_nuc_part = m_from.group(0)

        # Grab the fission part
        m_gd = re.search(gamma_decay_pattern, from_nuc_part)
        if m_gd is None:
            continue

        # Grab base data
        scale = float(m_gd.group(1))
        energy = float(m_gd.group(2))

        # Grab spectrum
        spectrum = np.array(m_gd.groups()[-1:1:-1], dtype=float)
        assert spectrum.shape == (G_g, )

        # Prepare the row
        gdrow['nuc'] = from_nuc

        gdrow['energy'] = energy
        gdrow['scaling_factor'] = scale

        gdrow['spectrum'] = spectrum

        # Write out the row
        gdrow.append()
        gamma_decay_table.flush()

    # Close the hdf5 file
    db.close()
Example #53
0
def gendecay(decays, branches, metastable_cutoff=1.0):
    """This computes ORIGEN TAPE9 decay data based on ENSDF data.

    Parameters
    ----------
    decays : list
        decay list from parse_ensdf()
    branches : list
        branches list from parse_ensdf()
    metastable_cutoff : float, optional
        minimum lifetime of metastable state (in seconds) to be included.

    Returns
    -------
    t9 : dict
        a TAPE9 dictionary for the decay library
    """
    t9 = {
        1: {
            '_type': 'decay',
            'title': 'PyNE Decay Data for Activation Products'
        },
        2: {
            '_type': 'decay',
            'title': 'PyNE Decay Data for Actinides & Daughters'
        },
        3: {
            '_type': 'decay',
            'title': 'PyNE Decay Data for Fission Products'
        },
    }
    for nlb, lib in t9.items():
        for field in origen22.DECAY_FIELDS:
            lib[field] = {}

    longest = {}
    longest2 = {}
    for item in decays:
        nuc = nucname.id(item[0])
        key = nucname.zzaaam(nuc)
        if _is_metastable_beta_decay_0(item, metastable_cutoff):
            if 'B-' in item[5]:
                _plus_eq_decay_t9(t9, 'frac_beta_minus_x', nuc, key,
                                  item[6] / 100.0)
            if 'B+' in item[5] or "EC" in item[5]:
                _plus_eq_decay_t9(t9, 'frac_beta_plus_or_electron_capture_x',
                                  nuc, key, item[6] / 100.0)
        if _is_metastable_beta_decay_x(item, metastable_cutoff):
            key += 1
            longest2[key] = longest2.get(key, 0)
            if item[1] == longest2[key]:
                if 'B-' in item[5]:
                    _plus_eq_decay_t9(t9, 'frac_beta_minus_x', nuc, key,
                                      item[6] / 100.0)
                    #item[6]*item[8]/100.0)
                if 'B+' in item[5] or "EC" in item[5]:
                    _plus_eq_decay_t9(t9,
                                      'frac_beta_plus_or_electron_capture_x',
                                      nuc, key, item[6] / 100.0)
                    #key, item[6]*item[8]/100.0)
            elif item[1] > longest2[key]:
                longest2[key] = item[1]
                if 'B-' in item[5]:
                    #_eq_decay_t9(t9, 'frac_beta_minus_x', nuc, key, item[6]*item[8]/100.0)
                    _eq_decay_t9(t9, 'frac_beta_minus_x', nuc, key,
                                 item[6] / 100.0)
                if 'B+' in item[5] or "EC" in item[5]:
                    _eq_decay_t9(t9, 'frac_beta_plus_or_electron_capture_x',
                                 nuc, key, item[6] / 100.0)
                    #key, item[6]*item[8]/100.0)
    for item in branches:
        nuc = nucname.id(item[0])
        key = nucname.zzaaam(nuc)
        if (item[1] == 0) and (item[2] > metastable_cutoff):
            _set_branch_item(t9, nuc, key, item)
        if (item[1] != 0) and (item[2] > metastable_cutoff):
            key += 1
            longest[key] = longest.get(key, 0)
            if (item[2] <= longest[key]):
                continue
            _set_branch_item(t9, nuc, key, item)
    for nucs, hl in zip([
            origen22.ACTIVATION_PRODUCT_NUCS,
            origen22.ACTINIDE_AND_DAUGHTER_NUCS, origen22.FISSION_PRODUCT_NUCS
    ], [t9[i]['half_life'] for i in range(1, 4)]):
        for nuc in nucs:
            key = nucname.zzaaam(nuc)
            if key not in hl:
                hl[key] = data.half_life(nuc)
    return t9
Example #54
0
def make_photon_fp_yields(nuc_data, build_dir):
    """Adds the photofission product yields to the hdf5 library.

    Parameters
    ----------
    nuc_data : str
        Path to nuclide data file.
    build_dir : str
        Directory with cinder.dat file.
    """
    # Open the HDF5 File
    db = tb.openFile(nuc_data, 'a', filters=BASIC_FILTERS)

    # Ensure that the appropriate file structure is present
    _init_cinder(db)

    # Read in cinder data file
    cinder_dat = os.path.join(build_dir, 'cinder.dat')
    with open(cinder_dat, 'r') as f:
        raw_data = f.read()

    # Get group sizes
    N_n, N_g = get_fp_sizes(raw_data)

    # get the info table
    info_table = grab_photon_fp_info(raw_data)

    # Grab the part of the file that is a neutron fission product yields
    m_yields = re.search(gfp_yields_pattern, raw_data, re.DOTALL)
    gfp_yields_raw = m_yields.group(0)

    # Init the neutron fission product info table
    gfp_table = db.createTable('/photon/cinder_fission_products/', 'yields',
                               np.empty(0, dtype=fp_yields_dtype),
                               'CINDER Photofission Product Yields')
    gfprow = gfp_table.row

    # Iterate over all to-nucs
    fp_to_nuc_pattern = fp_to_nuc_base + N_g * fp_to_nuc_insert + ")"
    for m_to in re.finditer(fp_to_nuc_pattern, gfp_yields_raw):
        to_nuc = nucname.zzaaam(m_to.group(2).strip())

        # Check matestable state
        if 1 < to_nuc % 10:
            # Metastable state too high!
            continue

        # Get the array of yield data
        yields = np.array(m_to.group(3).split(), dtype=float)
        assert len(yields) == N_g

        # Prep rows to the table
        for n in range(N_g):
            info = info_table[n]
            gfprow['index'] = info[0]
            gfprow['from_nuc'] = info[1]
            gfprow['to_nuc'] = to_nuc
            gfprow['mass_frac'] = yields[n]
            gfprow.append()

        # Write the table
        gfp_table.flush()

    # Close the hdf5 file
    db.close()
Example #55
0
def sigma_s_gh(nuc, temp=300.0, group_struct=None, phi_g=None, xs_cache=None):
    """Calculates the neutron scattering kernel for a nuclide.

    Parameters
    ----------
    nuc : int, str, Material, or dict-like 
        A nuclide or nuclide-atom fraction mapping.
    temp : float, optional
        Temperature [K] of material, defaults to 300.0.
    group_struct : array-like of floats, optional
        Energy group structure E_g [MeV] from highest-to-lowest energy, length G+1,
        defaults to xs_cache['E_g'].
    phi_g : array-like of floats, optional
        Group fluxes [n/cm^2/s] matching group_struct, length G, defaults to 
        xs_cache['phi_g'].
    xs_cache : XSCache, optional
        Cross section cache to use, defaults to pyne.xs.cache.xs_cache. 

    Returns
    -------
    sig_s_gh : ndarray 
        The scattering kernel, shape GxG.

    Notes
    -----
    This pulls the scattering length out of nuc_data library.

    Warnings
    --------
    This function is currently a stub until the proper way to compute the 
    scattering kernel is determined.  This function is safe to use but the 
    results are trivial.  This function simply returns an array with the 
    diagonal elements set to sigma_s as computed by pyne.xs.models.sigma_s().
    This conserves the calculation of sigma_s_g by summing sigma_s_gh over 
    the h-index.

    """
    xs_cache = cache.xs_cache if xs_cache is None else xs_cache
    _prep_cache(xs_cache, group_struct, phi_g)
    if isinstance(nuc,
                  collections.Iterable) and not isinstance(nuc, basestring):
        return _atom_weight_channel(sigma_s_gh,
                                    nuc,
                                    temp=temp,
                                    xs_cache=xs_cache)
    nuc = nucname.zzaaam(nuc)
    key = (nuc, 's_gh', temp)

    # Don't recalculate anything if you don't have to
    if key in xs_cache:
        return xs_cache[key]

    # Get some needed data
    E_g = xs_cache['E_g']
    G = len(E_g) - 1
    b = pyne.data.b(nuc)
    aw = pyne.data.atomic_mass(nuc)

    # OMG FIXME So hard!
    ## Initialize the scattering kernel
    #sig_s_gh = np.zeros((G, G), dtype=float)
    #
    ## Calculate all values of the kernel
    #for g, h in product(range(G), range(G)):
    #    # Numerator inetgration term
    #    dnumer = lambda _E_prime, _E: sigma_s_E(_E, b, M_A, T) *  P(_E, _E_prime, M_A, T) * xs_cache['phi_g'][g]
    #
    #    # Integral
    #    nE = 26
    #    E_space = np.logspace(np.log10(xs_cache['E_g'][g]), np.log10(xs_cache['E_g'][g+1]), nE)
    #    E_prime_space = np.logspace(np.log10(xs_cache['E_g'][h]), np.log10(xs_cache['E_g'][h+1]), nE)
    #
    #    numer = msmintegrate.dbltrapz(dnumer, E_space, E_prime_space)
    #
    #    # Denominator term, analytically integrated
    #    denom = xs_cache['phi_g'][g] * (xs_cache['E_g'][g+1] - xs_cache['E_g'][g])
    #
    #    # Cross section value
    #    sig_s_gh[g, h] = numer / denom

    # Temporary stub
    E_g_centers = (E_g[1:] + E_g[:-1]) / 2.0
    sig_s = pyne.xs.models.sigma_s(E_g_centers, b, aw, temp)
    sig_s_gh = np.diag(sig_s)

    xs_cache[key] = sig_s_gh
    return sig_s_gh