Source code for pyne.dbgen.atomic_mass

"""This module provides a way to grab and store raw data for atomic mass."""
from __future__ import print_function
import os
import re
import pkgutil
from warnings import warn
from pyne.utils import QAWarning

import numpy as np
import tables as tb

from pyne import nucname
from pyne.dbgen.api import BASIC_FILTERS
from pyne.dbgen.isotopic_abundance import get_isotopic_abundances

warn(__name__ + " is not yet QA compliant.", QAWarning)

# Note that since ground state and meta-stable isotopes are of the same atomic mass,
# the meta-stables have been discluded from the following data sets.

MASS_FILE = 'mass.mas12'


[docs]def copy_atomic_mass_adjustment(build_dir=""): """Copies the atomic mass evaluation originally from the Atomic Mass Data Center. These are courtesy of Georges Audi and Wang Meng via a private communication, November 2012.""" if os.path.exists(os.path.join(build_dir, MASS_FILE)): return mass = pkgutil.get_data('pyne.dbgen', MASS_FILE) with open(os.path.join(build_dir, MASS_FILE), 'wb') as f: f.write(mass)
# Note, this regex specifically leaves our free neutrons # amdc_regex = re.compile('[ \d-]*? (\d{1,3})[ ]{1,4}(\d{1,3}) [A-Z][a-z]? .*? (\d{1,3}) ([ #.\d]{10,11}) ([ #.\d]{1,10})[ ]*?$') amdc_regex = re.compile('[ \d-]*? (\d{1,3})[ ]{1,4}(\d{1,3}) [A-Z][a-z]? .*? (\d{1,3}) ([ #.\d]{5,12}) ([ #.\d]+)[ ]*?$')
[docs]def parse_atomic_mass_adjustment(build_dir=""): """Parses the atomic mass adjustment data into a list of tuples of the nuclide, atomic mass, and error.""" f = open(os.path.join(build_dir, MASS_FILE), 'r') atomic_masses = [] for line in f: m = amdc_regex.search(line) if m is None: continue nuc = (10000000 * int(m.group(1))) + (10000 * int(m.group(2))) mass = float(m.group(3)) + 1E-6 * float(m.group(4).strip().replace('#', '')) error = 1E-6 * float(m.group(5).strip().replace('#', '')) atomic_masses.append((nuc, mass, error)) f.close() return atomic_masses
atomic_mass_desc = { 'nuc': tb.IntCol(pos=1), 'mass': tb.FloatCol(pos=2), 'error': tb.FloatCol(pos=3), 'abund': tb.FloatCol(pos=4), } atomic_mass_dtype = np.dtype([ ('nuc', int), ('mass', float), ('error', float), ('abund', float), ])
[docs]def make_atomic_mass_table(nuc_data, build_dir=""): """Makes an atomic mass 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 = get_isotopic_abundances() atomic_masses = parse_atomic_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.id(element) A[nuc] = nuc, 0.0, 0.0, 0.0 for nuc, abund in atomic_abund.items(): zz = nucname.znum(nuc) element_zz = nucname.id(zz) 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, float(0.0 < new_elem_mass) A = sorted(A.values(), key=lambda x: x[0]) # Open the HDF5 File kdb = tb.open_file(nuc_data, 'a', filters=BASIC_FILTERS) # Make a new the table Atable = kdb.create_table("/", "atomic_mass", atomic_mass_desc, "Atomic Mass Data [amu]", expectedrows=len(A)) Atable.append(A) # Ensure that data was written to table Atable.flush() # Close the hdf5 file kdb.close()
[docs]def make_atomic_mass(args): """Controller function for adding atomic_mass.""" nuc_data, build_dir = args.nuc_data, args.build_dir if os.path.exists(nuc_data): with tb.open_file(nuc_data, 'r') as f: if hasattr(f.root, 'atomic_mass'): print("skipping atomic mass data table creation; already exists.") return # Then grab mass data print("Copying AME 2012 atomic mass data.") copy_atomic_mass_adjustment(build_dir) # Make atomic mass table once we have the array print("Making atomic mass data table.") make_atomic_mass_table(nuc_data, build_dir)